简体   繁体   English

为什么在Entity Framework中的类中有外键?

[英]Why have a foreign key in a class in Entity Framework?

Say I have 2 classes: Ninja has-many NinjaEquipment . 说我有2个班: Ninja有很多NinjaEquipment Inside NinjaEquipment , I have: public Ninja Ninja { get; set; } NinjaEquipment内部,我有: public Ninja Ninja { get; set; } public Ninja Ninja { get; set; } public Ninja Ninja { get; set; } . public Ninja Ninja { get; set; } I've seen some people also include a reference to the foreign key, such as: public int NinjaID { get; set; } 我见过有些人还包含对外键的引用,例如: public int NinjaID { get; set; } public int NinjaID { get; set; } public int NinjaID { get; set; } . public int NinjaID { get; set; } What's the point of doing this? 这样做有什么意义? Isn't a simple Ninja reference enough if I want to get to the "parent" of one-to-many relationship? 如果我想要达到一对多关系的“父母”,那么不是一个简单的Ninja参考吗?

What's the point of doing this? 这样做有什么意义?

I believe this is a difference between Foreign Key's and Navigation Properties . 我相信这是外键导航属性之间的区别。

Navigation properties provide a way to navigate an association between two entity types. 导航属性提供了一种导航两种实体类型之间关联的方法。 Every object can have a navigation property for every relationship in which it participates. 每个对象都可以为其参与的每个关系都有一个导航属性。 Navigation properties allow you to navigate and manage relationships in both directions, returning either a reference object (if the multiplicity is either one or zero-or-one) or a collection (if the multiplicity is many). 导航属性允许您在两个方向上导航和管理关系,返回参考对象(如果多重性是一个或零或一)或集合(如果多重性很多)。 You may also choose to have one-way navigation, in which case you define the navigation property on only one of the types that participates in the relationship and not on both. 您也可以选择单向导航,在这种情况下,您只能在参与关系的其中一种类型上定义导航属性,而不是两者都定义。

It is recommended to include properties in the model that map to foreign keys in the database. 建议在模型中包含映射到数据库中外键的属性。 With foreign key properties included, you can create or change a relationship by modifying the foreign key value on a dependent object. 如果包含外键属性,则可以通过修改依赖对象上的外键值来创建或更改关系。 This kind of association is called a foreign key association. 这种关联称为外键关联。 Using foreign keys is even more essential when working with N-Tier applications. 在使用N-Tier应用程序时,使用外键更为重要。 Note, that when working with 1-to-1 or 1-to-0..1 relationships, there is no separate foreign key column, the primary key property acts as the foreign key and is always included in the model. 请注意,当使用1对1或1对0..1关系时,没有单独的外键列,主键属性充当外键并始终包含在模型中。

When foreign key columns are not included in the model, the association information is managed as an independent object. 当外键列未包含在模型中时,关联信息作为独立对象进行管理。 Relationships are tracked through object references instead of foreign key properties. 通过对象引用而不是外键属性来跟踪关系。 This type of association is called an independent association. 这种类型的关联称为独立关联。 The most common way to modify an independent association is to modify the navigation properties that are generated for each entity that participates in the association. 修改独立关联的最常用方法是修改为参与关联的每个实体生成的导航属性。

This information can be found at this source . 此信息可在此来源找到。

You're right, you don't need to add the ID column as a property within your models, Entity Framework is intelligent enough to generate your foreign key column for you and your relationship between the tables in most cases. 您是对的,您不需要将ID列添加为模型中的属性,实体框架足够智能,可以为您生成外键列以及在大多数情况下表之间的关系。

Personally, when I was setting up my website, I had an existing database that I wanted to use with Entity Framework, so I needed the control. 就个人而言,当我设置我的网站时,我有一个我想要与Entity Framework一起使用的现有数据库,所以我需要控件。 I added the foreign key properties myself and set up the mappings between the two tables using the Fluent API because I had foreign key columns with names that didn't match with the Entity Framework convention . 我自己添加了外键属性,并使用Fluent API设置了两个表之间的映射,因为我的外键列的名称与Entity Framework 约定不匹配。

For example: 例如:

public class NinjaEquipmentMap : EntityTypeConfiguration<NinjaEquipment>
{
    public NinjaEquipmentMap
    {
        // Fluent API examples:

        // Describes the relationship between the entities 
        // and the property to use as the foreign key.
        this.HasRequired(t => t.Ninja)
            .WithMany(c => c.NinjaEquipment)
            .HasForeignKey(c => c.NinjaId);

        // I can specify a relationship using a property name
        // that existed in my existing database.
        this.HasRequired(t => t.Ninja)
            .WithMany(c => c.NinjaEquipment)
            .HasForeignKey(c => c.SuperNinjaId);
    }
}

If you were creating a new database from scratch, it may be acceptable to allow Entity Framework to do the leg work and generate the columns for you. 如果您从头开始创建新数据库,则可以接受允许实体框架执行支持并为您生成列。

Another reason that I can think of is that you may want to expose the foreign key value in your model. 我能想到的另一个原因是您可能希望在模型中公开外键值。

// 
// BEFORE
// 
var ninjaEquipment = dbContext.Set<NinjaEquipment>().Find(1);

// We have to load the Ninja record to find out the related Ninja ID
var ninjaId = ninjaEquipment.Ninja.Id;

// 
// AFTER
// 
var ninjaEquipment = dbContext.Set<NinjaEquipment>().Find(1);

// Find out the Ninja equipment ID without having to load the Ninja
var ninjaId = ninjaEquipment.NinjaId;

I personally like the control :o) 我个人喜欢控件:o)

It is the same as you design your tables in the database. 它与您在数据库中设计表格相同。 You must have a foreign key to have the relations between them. 您必须有一个外键才能拥有它们之间的关系。 This is what Navigation Properties depends on. 这就是导航属性所依赖的。 for more reading https://msdn.microsoft.com/en-us/data/jj713564.aspx 更多阅读https://msdn.microsoft.com/en-us/data/jj713564.aspx

It's generally useful when you need the ID of the child/parent item: for example if you have NinjaID within NinjaEquipment , you won't need to lazy-load (or include) the Ninja navigation property. 当您需要子/父项的ID时,它通常很有用:例如,如果您在NinjaID中有NinjaEquipment ,则不需要延迟加载(或包含) Ninja导航属性。

This results in simpler requests, ie with less SQL JOINs. 这导致更简单的请求,即SQL JOIN更少。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM