首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架6和集合

实体框架6和集合
EN

Stack Overflow用户
提问于 2013-12-17 04:35:04
回答 2查看 16.3K关注 0票数 8

我正在开发我的第一个实体框架应用程序。我正在使用EF vesion 6(来自Nuget)和.net 4.0。然而,我在一些事情上有些困难,对我来说,这似乎是非常简单的事情。我在互联网上发现了很多相互矛盾的建议和解决方案,但在花了几天时间试图解决问题之后,我真的很困惑,甚至要质疑我对实体框架的一些基本理解。我想做的是:创建一个简单的相关实体集合,并在从父实体中删除它们时自动删除它们。

这里是我如何在香草C#模型。与Microsoft示例保持一致,假设我们有两个类,Post和Tag,如下所示:

代码语言:javascript
复制
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,我想出了这个结构,它能做我想做的事情:

代码语言:javascript
复制
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; }
}

TagPost的标记集合中删除时,实体框架将为标记发出一个DELETE,如下所示(#2):http://www.kianryan.co.uk/2013/03/orphaned-child/

同样,向post添加标记将自动发出INSERT并设置FK关系。

需要注意的一点是:确保使用virtual!我认为这也是我很多挫折的根源。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-17 05:08:22

也尝试从Tag端定义关系,指定每个Tag与单个Post相关,并且是必需的。

PostTag中添加必需的导航属性:

代码语言:javascript
复制
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:

代码语言:javascript
复制
modelBuilder.Entity<Post>().HasMany( p => p.Tags ).WithRequired();
票数 3
EN

Stack Overflow用户

发布于 2015-03-12 12:50:15

这可能是线亡灵,但我没有代表只是评论。下面这些不就是你想做的吗?

代码语言:javascript
复制
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是虚拟的,没有什么是虚拟的。您可能也可以使用基本的键注释。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20625991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档