【问题标题】:Difference between two foreign key approaches in code first Entity Framework代码优先实体框架中两种外键方法之间的区别
【发布时间】:2018-12-02 21:27:07
【问题描述】:

我是 asp.net MVC 和数据库的新手。我发现有两种方法可以创建外键关系。

方法一:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<Vehicle> vehicles { get; set; }
}

public class Vehicle
{
    public int Id { get; set; }
    public string lic_number { get; set; }
}

第二种方式是:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Vehicle
{
    public int Id { get; set; }
    public string lic_number { get; set; }
    public virtual Person person { get; set; }
}

请告诉我这两种方法有什么不同。

感谢您阅读我的问题。

【问题讨论】:

标签: c# asp.net entity-framework foreign-keys ef-code-first


【解决方案1】:

这两种方法没有区别,都达到了相同的目标。只是一种不同的做事方式。

下面说 Person 有很多 Vehicles。

public class Person
{
    public virtual List<Vehicle> vehicles { get; set; }
}

下面说车辆属于一个人

public class Vehicle
{
    public virtual Person person { get; set; }
}

所以两者都是一样的。

【讨论】:

    【解决方案2】:

    这些方法的结果将是相同的 - 创建一对多的关系。

    但是,您可能希望通过以下方式编写域类 - 可以轻松地从两个对象访问相关属性。

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public virtual ICollection<Vehicle> Vehicles { get; set; }
    }
    
    public class Vehicle
    {
        public int Id { get; set; }
        public string lic_number { get; set; }
    
        public virtual Person Person { get; set; }
        public int PersonId { get; set; }
    }
    

    这将根据代码自动生成关系。如果你想在设计时明确你可以使用 Fluent Api 方法。 Check here

    【讨论】:

      【解决方案3】:

      您希望设计每个Person 有零个或多个Vehicles,并且每个Vehicle 恰好属于一个Person。

      为了更清楚地表达这一点,我会使用这两种声明。这对于您的代码的未来读者来说会更容易。此外,您的查询不需要连接。

      class Person
      {
          public int Id { get; set; }
          public string Name { get; set; }
          // every Person has zero or more Vehicles:
          public virtual ICollection<Vehicle> Vehicles { get; set; }
      }
      
      class Vehicle
      {
          public int Id { get; set; }
          public string LicenseNumber { get; set; }
      
          // every vehicle belongs to exactly one Person using foreign key
          public int PersonId {get; set;}
          public virtual Person Person {get; set;}
      }
      

      对于这辆车的所有者来说,也许 Owner 是一个更好的名字。

      请注意,我已经声明了表格的所有列。表之间的关系被声明为虚拟的:它们不是表的真实部分。

      我已将List&lt;Vehicle&gt; 更改为ICollection&lt;Vehicle&gt;。毕竟,Vehicle[4] 会有明确的含义吗?

      除了这样你的表之间的关系对读者来说更清楚,你的查询会更简单:

      “给我所有拥有两辆或更多车辆的人的身份证和姓名”

      var result = myDbcontext.Persons
          .Where(person => person.Vehicles.Count >= 2)
          .Select(person => new
          {
               Id = person.Id,
               Name = person.Name,
          })
      

      “给我所有车辆年龄超过...的人员的 ID 和姓名”

      var result = myDbContext.Persons.Select(person => new
      {
          Id = person.Id,
          Name = person.Name,
          OldVehicles = person.Vehicles
              .Where(vehicles => vehicle.CreationDate < OldDate)
              .ToList(),
      });
      

      “把所有旧车连同车主的身份证和姓名一起给我”

      var result = myDbContext.Vehicles
          .Where(vehicle => vehicle.CreationDate < OldDate)
          .Select(vehicle => new
          {
              LicenseNumber = vehicle.LicenseNumber,
              Owner = new
              {
                   Id = vehicle.Person.Id,
                   Name = vehicle.Person.Name,
              },
          });
      

      通过使用表之间的关系,您将不再需要连接外键。实体框架会理解需要一个连接(不确定这是否对 ef-core 也有效)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-30
        • 1970-01-01
        • 2011-08-05
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        • 2015-02-24
        相关资源
        最近更新 更多