我正在开发我的第一个实体框架应用程序。我正在使用EF vesion 6(来自Nuget)和.net 4.0。然而,我在一些事情上有些困难,对我来说,这似乎是非常简单的事情。我在互联网上发现了很多相互矛盾的建议和解决方案,但在花了几天时间试图解决问题之后,我真的很困惑,甚至要质疑我对实体框架的一些基本理解。我想做的是:创建一个简单的相关实体集合,并在从父实体中删除它们时自动删除它们。
这里是我如何在香草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在从db加载时会有0个元素,尽管SQL explorer显示PostId值是正确的,等等。我使用了一些技巧,比如将Tag.PostId标记为键、手动删除标记、将标记添加到上下文中作为DbSet、手动设置myTag.Post = null; (我尝试了启用和禁用Lazy加载,以确定它的价值-但如果可能的话,我希望将其关闭)。
现在(在很大程度上感谢看似矛盾和过于复杂的例子),我感到非常困惑和迷失。有人能确切地告诉我如何在EF中建立这种关系吗?(顺便说一句,我正在使用代码)
解决办法:
多亏了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; }
}当Tag从Post的标记集合中删除时,实体框架将为标记发出一个DELETE,如下所示(#2):http://www.kianryan.co.uk/2013/03/orphaned-child/
同样,向post添加标记将自动发出INSERT并设置FK关系。
需要注意的一点是:确保使用virtual!我认为这也是我很多挫折的根源。
发布于 2013-12-17 05:08:22
也尝试从Tag端定义关系,指定每个Tag与单个Post相关,并且是必需的。
在Post中Tag中添加必需的导航属性:
public class Tag
{
// you need an ID
public int Id { get; set; }
public string Text { get; set; }
[Required]
public virtual Post Post { get; set; }
}或者,如果您真的不想添加导航属性,可以使用Fluent API:
modelBuilder.Entity<Post>().HasMany( p => p.Tags ).WithRequired();发布于 2015-03-12 12:50:15
这可能是线亡灵,但我没有代表只是评论。下面这些不就是你想做的吗?
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 int PostId { get; set; }
[ForeignKey("PostId")]
public virtual Post Post { get; set; }
}PostId从数据库中加载,然后作为外键(通过注释)使用到Post类中。Post是虚拟的,没有什么是虚拟的。您可能也可以使用基本的键注释。
https://stackoverflow.com/questions/20625991
复制相似问题