【问题标题】:Is it important to define both ends of relationships/FKs with Entity Framework?使用实体框架定义关系/FK 的两端是否重要?
【发布时间】:2016-12-17 00:11:32
【问题描述】:

使用 EntityFramework,我很好奇当您指定外键的两端而不是只指定一个时是否会提高性能。假设我有一个大多数其他表使用的表,例如查找表。假设这个表 LookupValue 有 20 个传入的外键,而另一个表 User 通过 TypeId 列位于其中一个外键的另一端。

LookupValue
------------------
Id       INT     <--\
Values   NVARCHAR   |
                    |
User                | FK_User_NameValue
------------------  |
Id       INT        |
TypeId   INT     <--/

使用代码优先,我将这些表定义如下:

modelBuilder
    .Entity<LookupValue>()
    .ToTable("LookupValue")
    .HasKey(o => o.Id);

modelBuilder
    .Entity<User>()
    .ToTable("User")
    .HasKey(o => o.Id)
    .HasRequired(o => o.Type)
    .WithMany(o => o.UsersOfThisType)
    .HasForeignKey(o => o.TypeId);

我的问题是...

  • WithMany...HasForeignKey 部分对 EF 是否必要或有助于 EF 更好地在这两个表之间生成查询?
  • 除了通过代码导航之外,导航属性还有其他作用吗?
  • 如果我没有指定关系的另一端,EF 是否会知道这个外键关系?

例如:

modelBuilder
    .Entity<User>()
    .ToTable("User")
    .HasKey(o => o.Id)
    .HasRequired(o => o.Type);

【问题讨论】:

    标签: c# sql-server entity-framework linq foreign-keys


    【解决方案1】:

    只要你只需要从User遍历到LookupValue,就可以在User中有accessor属性。如果您不需要查找引用 LookupValue 的所有用户,则无需在 LookupValue 对象中包含 ICollection

    public class LookupValue
    {
        public int Id { get; set; }
        public string Value { get; set; }
    }
    
    public class User
    {
        public int Id { get; set; }
        public int TypeId { get; set; }
    
        public LookupValue Type { get; set; }
    }
    

    Entity Framework 将通过 Users 中的 TypeId 属性生成从用户到 LookupValues 的外键。我认为这就是从用户到 LookupValue 的高性能遍历所需要的全部内容。

    【讨论】:

    • 另外,附注:在这种简单的情况下,您甚至可能不需要重写 OnModelCreating 并使用 Fluent API。使用这里的类,Entity Framework 足够聪明地推断出哪个属性是外键,因为 Type 是访问器并且存在 TypeId 属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多