在 Entity Framework 中不需要声明关系时 6?

When declaring relationship is not necessary in Entity Framework 6?

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

今天(偶然)我删除了两个表之间的一种关系,一切都保持良好。我感到非常惊讶,因为 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,那是不是说流利的API大部分时间都是1:1?

Entity Framework 有一些您不需要明确定义的约定。

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

In addition to navigation properties, we recommend that you include foreign key properties on the types that represent dependent objects. Any property with the same data type as the principal primary key property and with a name that follows one of the following formats represents a foreign key for the relationship: '<navigation property name><principal primary key property name>', '<principal class name><primary key property name>', or '<principal primary key property name>'. If multiple matches are found then precedence is given in the order listed above. Foreign key detection is not case sensitive. When a foreign key property is detected, Code First infers the multiplicity of the relationship based on the nullability of the foreign key. If the property is nullable then the relationship is registered as optional; otherwise the relationship is registered as required.