我正在开发我的第一个Entity Framework应用程序,我正在使用EF版本6(来自Nuget)和.NET 4.0。然而,我遇到了一些困难,对我来说似乎应该非常简单。我在互联网上找到了很多相互矛盾的建议和解决方案,但是经过几天的努力,我真的很困惑,并且开始质疑我对Entity Framework的一些基本理解。我想要做的是这样的:创建一个简单的相关实体集合,并在从父项中删除它们时自动删除它们。
以下是我将如何在普通C#中建模。按照Microsoft示例,假设我们有两个类Post和Tag,如下所示:
当从
需要注意的一点是:确保您使用了virtual!我认为这也是我的许多挫败的根源。
public class Post
{
public string Name { get; set; }
public string Author { get; set; }
public ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public string Text { get; set; }
// Possibly other properties here
}
那么,添加标签就像 myPost.Tags.Add(myTag)
一样简单,删除标签就像 myPost.Tags.Remove(myTag)
一样简单。
现在让我们看看Entity Framework方面的事情:我看到这个并想到了“外键,当然!”,但是我添加FK时遇到了很多问题:当从帖子中删除标签时,标签不会从数据库中删除,尽管SQL浏览器显示PostId值正确,但加载时myPost.Tags
将具有0个元素,我折腾了很多技巧,例如将 Tag.PostId
标记为Key、手动删除Tags、实际上作为DbSet将Tag添加到上下文中、手动设置 myTag.Post = null;
(我尝试启用和禁用Lazy loading,不知道是否有用-尽管如果可能,我想将其关闭)
现在(在很大程度上得益于似乎矛盾和过于复杂的示例),我感到非常困惑和失落。有人能告诉我如何在EF中设置这种关系吗?(顺便说一下,我正在使用Code First)
解决方案:
多亏了Moho,我想出了这个结构,它正好符合我的要求:
public class Post
{
public int Id { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public Post()
{
Tags = new HashSet<Tag>();
}
}
public class Tag
{
[Key, Column(Order=1), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Text { get; set; }
// Possibly other properties here
public virtual Post Post { get; set; }
[Key, Column(Order=2)]
public virtual int PostId { get; set; }
}
public class TestContext : DbContext
{
public DbSet<Post> Posts { get; set; }
}
当从
Post
的标签集合中删除Tag
时,Entity Framework会发出一个DELETE tag的命令,如此处所述 (#2):http://www.kianryan.co.uk/2013/03/orphaned-child/
同样地,将标签添加到帖子中会自动发出INSERT并设置FK关系。需要注意的一点是:确保您使用了virtual!我认为这也是我的许多挫败的根源。
null
,那么可能是查询出了问题。 - trinaldi