2012-01-04 97 views
0

我新的EF和CodeFirst和我有以下(簡化)模型導航屬性:與附加約束

public class Comment 
{ 
    public int ID {get; set;} 
    public int SourceType {get; set;} 
    public int SourceID {get; set;} 
    public string Name {get; set;} 
    public string Text {get; set;} 
} 

public class Photo 
{ 
    public int ID {get; set;} 
    public virtual ICollection<Comment> Comments {get; set;} 
} 

public class BlogPost 
{ 
    public int ID {get; set;} 
    public virtual ICollection<Comment> Comments {get; set;} 
} 

在我實際的數據庫,我只有茨艾倫三個表。 我的目標是製作一張表格「評論」,用於存儲用戶發佈的照片​​以及博客帖子的評論。 Comment.SourceType字段應區分發布到照片(SourceType == 1)或博客文章(SourceType == 2)的評論,而Comment.SourceID字段告訴我源的ID。

Photo photo = DbContext.Photos.Find(15); //some photo with ID 15 
BlogPost blog = DbContext.BlogPost.Find(15); //some blog post, also with ID 15 

Comment photoComment = new Comment(); 
photoComment.SourceType = 1; //photo 
photoComment.SourceID = photo.ID; 
photoComment.Name = "John"; 
photoComment.Text = "This is a very nice picture!"; 

Comment blogComment = new Comment(); 
blogComment.SourceType = 2; //blog post 
blogComment.SourceID = blog.ID; 
blogComment.Name = "Peter"; 
blogComment.Text = "An interesting blog post!"; 

DbContext.Comments.Add(photoComment); 
DbContext.Comments.Add(blogComment); 
DbContext.SaveChanges(); 

//... 

Photo photoFromBefore = DbContext.Photos.Find(15); 
foreach(Comment comment in photoFromBefore.Comments) 
    Console.Write(comment.Name+"("+comment.SourceType+", "+comment.SourceID+"); "); 
//Output will be: "John(1, 15); Peter(2, 15);" 
//Desired output should be instead just "John(1, 15);" 
//because Peter's comment actually belongs to blog post with 
//the same ID but different "SourceType"-identifier in my database table. 

我希望它能以某種方式清楚我想要達到的目標。基本上,我不希望有多個表photo_comments,blogpost_comments等等,可以在我的網站上發表評論。

我能以某種方式告訴EF僅加載與SourceType==1(對於照片)的評論嗎?有什麼類型的「約束」或「限制」我可以用來實現這一點?

回答

0

你應該可以在你的foreach語句中使用LINQ where子句。

foreach(Comment comment in photoFromBefore.Comments.Where(x=>x.SourceType == 2)) 

而且,看代碼,應該在foreach上面的線是

IEnumerable<Photo> photoFromBefore = DbContext.Photos.First(15); 
+0

這就是我試圖避免雖然:) EF的全部目的就是少做工作。我知道我可以手動加載評論,但是Photo.Comments是一個導航屬性,當我調用它時,它會自動加載所有照片的評論。 另外,你對錯誤的代碼是正確的。我有一個錯誤(「第一」而不是「查找」),我現在糾正。謝謝。 – 2012-01-04 11:35:34

+0

你的問題是照片和博客是兩個不同的表格(對吧?)。由於它們是兩個不同的表,它們將具有兩組主鍵。因此 - 您可以使用Id 1創建博客,使用Id 1創建一張照片。EF無法知道基於該Id加載哪個註釋,而無需在查找語句中指定where子句(sourcetype == x)。導航屬性是FK的一個代碼等價物 - 您可以將該值映射到表格a col x到表b col y。如果您試圖避免使用where子句,則可以將源類型存儲在照片和博客表中... – Tommy 2012-01-04 14:12:42

+0

是的,我意識到問題:)我試圖弄清楚是否有辦法使EF _know_加載哪條評論。例如使用Fluid API。使用'modelBuilder.Entity ().Property(p => p.Comments).HasCondition(c => c.SourceType == 1);'''和'modelBuilder.Entity (())替代'OnModelCreating(DbModelBuilder modelBuilder) ).Property(b => b.Comments).HasCondition(c => c.SourceType == 2);'。我只是在這裏吐口水,但我想知道這樣的事情是否可能? – 2012-01-04 20:58:44