C# 在实体框架6中何时不需要声明关系?

C# 在实体框架6中何时不需要声明关系?,c#,entity-framework,entity-framework-6,ef-fluent-api,navigation-properties,C#,Entity Framework,Entity Framework 6,Ef Fluent Api,Navigation Properties,在EF6中,我们有两种方法来声明两个表之间的关系: 注释属性 Fluent API 今天我无意中删除了两个表之间的一个关系,一切都很顺利。我非常惊讶,因为EF不可能知道这两个表是如何连接的 表如下所示: Fluent API: 下面是我做的测试:这是一个集成测试,连接到真实的数据库,获取带有注释的项目,并测试EF: [TestCase] public void QueryItemWithItemNotesTest() { FniContext fniCon

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

注释属性

Fluent API

今天我无意中删除了两个表之间的一个关系,一切都很顺利。我非常惊讶,因为EF不可能知道这两个表是如何连接的

表如下所示:

Fluent API:

下面是我做的测试:这是一个集成测试,连接到真实的数据库,获取带有注释的项目,并测试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:1,那么这是否意味着Fluent API大部分时间都是1:1使用的?

实体框架有一些约定,您不需要明确定义

除了导航属性外,我们建议您包括 表示从属对象的类型的外键属性。 与主主键具有相同数据类型的任何属性 属性,并且名称遵循以下格式之一 表示关系的外键:,或。如果找到多个匹配项,则在 上面列出的订单。外键检测不区分大小写。什么时候 当检测到外键属性时,代码首先推断其多重性 基于外键的可空性的关系。如果 属性可为Null,则关系注册为 可选择的否则,将根据需要注册关系


即使在db级别,您也不真正需要FK约束。您可以直接在数据库中使用原始sql测试它,其中包含两个不带FKs的表。换言之,选择“使用连接工作”事件而不使用FK约束。但是,这些限制是有原因的,你应该始终使用它们:好吧,回到你的问题,EF惯例在你的案例中获胜了。哦,我很幸运,因为名字符合惯例。但哪些名字很重要?注释中的C类成员名称或数据库列名?在引号中,它表示虽然有点不清楚,但它与属性及其名称有关。因此,它是属性的名称,而不是数据库中的列名。哦,听起来你可以有假FK,但不知道它,而数据库中没有真正的FK。我不确定我是否喜欢它
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);
    }    
}
    [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);
    }