2013-02-01 27 views
1

我有一個奇怪的問題與實體框架,如果我試圖訪問用戶變量不是當前用戶它會引發錯誤。我正在使用帶有SignalR的ASP.NET MVC 4(這是在SignalR集線器中)和SimpleMembership來提供身份驗證。如果用戶不是當前用戶,EF將不會返回用戶?

這裏是我的代碼:

using (CfDb db = new CfDb()) 
{ 
    var currUser = db.Users.FirstOrDefault(a => a.ID == UserID); 
    if (currUser != null && currUser.Challenge == Challenge) 
    { 
     var posts = db.Posts.Where(a => a.Privacy == "public").OrderByDescending(a => a.PostedTime); 
     List<int> People = new List<int>(); 
     foreach (Post post in posts) 
     { 
      People.Add(post.Poster.ID); 
     } 
    } 
} 

如果post.Poster相同登錄的用戶將返回誰張貼的帖子正確的用戶的電流,但如果沒有,post.Poster將是無效和post.Poster.ID會拋出異常。如果我取出所有currUser代碼(並且只要做到(true)),錯誤仍然會發生,因此它似乎與currUser變量無關。我甚至沒有使用WebSecurity做任何事情 - 從頁面頂部刪除using System.Web.Security;並不能解決問題。我不知道如何知道當前用戶是誰,看起來很奇怪,它只是返回海報,如果它是當前用戶。

這裏是我的代碼第一個模型的重要組成部分:

public class User 
{ 
    [Key] 
    public int ID { get; set; } 

    [Required] 
    public string Username { get; set; } 
    [Required] 
    public string Email { get; set; } 
    [Required] 
    public string Realname { get; set; } 
    [Required] 
    public DateTime JoinDate { get; set; } 
    public virtual ICollection<User> Friends { get; set; } 
    [Required] 
    public string Challenge { get; set; } 
    public School School { get; set; } 
    public int Grade { get; set; } 
    [Required] 
    public double Vici { get; set; } 
    public virtual ICollection<Classroom> Classes { get; set; } 
} 
public class Post 
{ 
    public int ID { get; set; } 
    [Required] 
    public double Vici { get; set; } 
    public User Poster { get; set; } 
    public Classroom Class { get; set; } 
    [Required] 
    public string Content { get; set; } 
    public virtual ICollection<User> Likes { get; set; } 
    public virtual ICollection<Comment> Comments { get; set; } 
    public string Type { get; set; } 
    public string Privacy { get; set; } 
    [Required] 
    public DateTime PostedTime { get; set; } 
} 
public class CfDb : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
    public DbSet<Post> Posts { get; set; } 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Post>().HasMany(e => e.Likes).WithMany(); 
     modelBuilder.Entity<User>().HasMany(e => e.Friends).WithMany(); 
     modelBuilder.Entity<Post>().HasMany(e => e.Comments).WithMany(); 
     modelBuilder.Entity<Comment>().HasMany(e => e.Likes).WithMany(); 
    } 
} 

在我的數據庫中,Poster_ID列都設置正確,這樣似乎並不成爲問題。

感謝您的幫助!

回答

0

您或者需要告訴EF急於加載您的用戶屬性,在查詢中訪問它,或者使其成爲虛擬的,以便代理可以延遲加載它們 - 這與您如何設置集合類似。它與當前用戶一起工作,因爲該對象已被加載。

如:

var posts = db.Posts.Where(a => a.Privacy == "public") 
        .OrderByDescending(a => a.PostedTime) 
        .Select(a=> new { Post = a, User = a.Poster }); 

foreach (var post in posts) { 
    People.Add(post.User.Id); 
} 
+0

使其虛擬完美工作,感謝你:) – MatthewSot

+1

請記住,這將使它延遲加載。如果您正在處理100個帖子,那麼當您嘗試訪問post.User.Id時,它將針對每個用戶對數據庫執行新的查詢。如果您將其保留爲虛擬並使用與我發佈的查詢類似的查詢,您將急切地加載相關的用戶。 ORM中這種常見的呃逆稱爲N + 1問題。 – drch

相關問題