【问题标题】:When declaring relationship is not necessary in Entity Framework 6?在 Entity Framework 6 中不需要声明关系时?
【发布时间】:2018-03-08 20:47:24
【问题描述】:

在 EF6 中,我们有两种方式来声明两个表之间的关系:

  • 注解属性

  • Fluent API

今天(偶然)我删除了两个表之间的一个关系,一切都运行良好。我很惊讶,因为 EF 无法知道这两个表是如何连接的。

表格如下所示:

[Table("item")]
public class Item
{
    public Item()
    {
        ItemNotes = new HashSet<ItemNote>();
    }
    [Key]
    [Column("itemID", TypeName = "int")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int itemID { get; set; }

    public ICollection<ItemNote> ItemNotes { get; set; }
}

[Table("itemNotes")]
public class ItemNote
{
    [Key]
    [Column("id", TypeName = "int")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    [Column("itemID", TypeName = "int")]
    public int ItemId { get; set; }
    [Column("note", TypeName = "varchar")]
    [MaxLength(255)]
    public string Note { get; set; }
}    

流畅的 API:

public class MyContext : DbContext
{
    public MyContext()
        : base("name=MyContext")
    {
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<MyContext>(null);

        //I removed this relationship:
        //modelBuilder.Entity<Item>().HasMany(i => i.ItemNotes).WithRequired().HasForeignKey(i => i.ItemId);

        base.OnModelCreating(modelBuilder);
    }    
}

这是我做的测试:这是一个集成测试,连接到真实的数据库,获取带有注释的项目并测试 EF:

    [TestCase]
    public void QueryItemWithItemNotesTest()
    {
        FniContext fniContext = new FniContext();

        int itemId = fniContext.Database.SqlQuery<int>("SELECT TOP(1) itemId FROM item WHERE itemId IN (SELECT itemId FROM dbo.itemNotes)").FirstOrDefault();
        var item = fniContext.Items.AsNoTracking()
            .Include(i => i.ItemNotes)
            .Where(i => i.itemID == itemId).FirstOrDefault();

        Assert.IsNotNull(item);
        Assert.Greater(item.ItemNotes.Count, 0);
    } 

通过了!它加载所有笔记! 怎么会?!

我一直在调查,结果发现在 1:many 关系的情况下,我完全不必在代码中存在任何关系。我唯一需要的是 1:1 的关系。我错过了什么吗?大多数关系是 1:many,那么是不是说 Fluent API 大部分时间都是 1:1 使用的?

【问题讨论】:

  • 即使在数据库级别上,您也不需要 FK 约束。您可以直接在数据库中使用原始 sql 测试它,并使用两个没有 FK 的表。换句话说,带有连接的 SELECT 可以在没有 FK 约束的情况下工作。但是,存在这些限制是有原因的,您应该始终使用它们:linkedin.com/pulse/importance-foreign-key-constraint-tim-miles 好吧,回到您的问题,EF 约定在您的案例中胜出。

标签: c# entity-framework entity-framework-6 ef-fluent-api navigation-properties


【解决方案1】:

实体框架有一些你不需要明确定义的约定。

来自https://msdn.microsoft.com/en-us/library/jj679962(v=vs.113).aspx#Anchor_2

除了导航属性,我们建议您包括 表示依赖对象的类型的外键属性。 与主主键具有相同数据类型的任何属性 属性并具有遵循以下格式之一的名称 表示关系的外键:'', '',或''。如果找到多个匹配项,则在 上面列出的顺序。外键检测不区分大小写。什么时候 检测到外键属性,Code First 推断出多重性 基于外键可空性的关系。如果 该属性可以为空,然后该关系被注册为 选修的;否则按要求注册关系。

【讨论】:

  • 哦,所以我很“幸运”,因为名称符合约定。但哪些名字很重要? C# 类成员名称或数据库列名称(在注释中)?
  • 在引用中它指出(虽然有点不清楚),它是关于一个属性及其名称的。所以它是属性的名称,而不是数据库中的列名。
  • 哦,听起来你可以有假的 FK(并且不知道它),而数据库中没有真正的 FK。我不确定我喜欢它
猜你喜欢
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多