【发布时间】:2013-12-17 04:35:04
【问题描述】:
我正在开发我的第一个实体框架应用程序。我正在使用 EF vesion 6(来自 Nuget)和 .net 4.0。但是,在我看来,这似乎应该非常简单。我在互联网上发现了很多相互矛盾的建议和解决方案,但是在花了几天时间试图解决问题之后,我真的很困惑,并且到了质疑我对实体框架的一些基本理解的地步。我想做的是:创建一个简单的相关实体集合,并在它们从父级中删除时自动删除它们。
以下是我将如何在 vanilla C# 中对此进行建模。为了与 Microsoft 示例保持一致,假设我们有两个类,Post 和 Tag,如下所示:
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)一样简单。
现在到实体框架方面:我看了看,想“当然是外键!”但是我在添加 FK 时遇到了很多问题:标签从帖子中删除时不会从数据库中删除,myPost.Tags 从数据库加载时将有 0 个元素,尽管 SQL 资源管理器显示 PostId 值为正确,等等。我迷惑了一堆技巧,比如将Tag.PostId标记为键,手动删除标签,实际上将标签作为DbSet添加到上下文中,手动设置myTag.Post = null;(我尝试同时启用延迟加载和禁用,因为它的价值 - 虽然如果可能的话我想保持关闭)
现在(很大程度上归功于看似矛盾和过于复杂的示例),我很困惑和迷茫。有人可以确切地告诉我应该如何在 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 时,实体框架将为标签发出 DELETE,如下所述 (#2):http://www.kianryan.co.uk/2013/03/orphaned-child/
同样,在帖子中添加标签会自动发出 INSERT 并设置 FK 关系。
需要注意的一点:确保使用virtual!我想这也是我很多挫败感的根源。
【问题讨论】:
-
你没有把
Id属性和EF做关系?您能否举例说明您是如何进行查询的? -
@Tico 我遗漏了 EF 实现的东西,这是故意的 - 我想避免我的实际实现中的任何负面影响/先入之见(更不用说它在我摆弄它时发生了很大变化! ) 这样我就可以从一开始就获得有关如何设置它的建议。与我的示例查询相同的故事,尽管我设想我的用例是这样的:“1)使用一些初始标签创建的帖子 2)帖子的标签被编辑,一些被删除,一些被添加。3)帖子被保存。”
-
所以我猜你对上下文和其他东西很熟悉。因为您在 SQL 中确实有一些数据。使用 LINQ 查询其中之一。如果它仍然返回
null,则您的查询可能有问题。 -
你我的朋友绝对是个天才!我一直把头撞在墙上,试图完成这项工作,你的解决方案完全符合我的要求。
标签: c# entity-framework