简体   繁体   English

EF的代码优先,如何在不设置数据库表之间外键的情况下定义导航属性关系

[英]Code first of EF, how to define navigation property relationship without setting foreign key between table in database

I use code first of Entity framework. 我首先使用实体​​框架的代码。 There are two classes "Question" and "User". 有两个类“问题”和“用户”。 I defined a relationship as below: 我定义了如下关系:

this.HasRequired(v => v.Creator).WithMany(v => v.Questiones)
.HasForeignKey(v => v.CreatorId).WillCascadeOnDelete(false);

After gernerating the database I found that it always create foreign key between Id of User and CreatorId of Question. 整理数据库后,我发现它总是在User的ID和Question的CreatorId之间创建外键。 Because of lower performance of FK(and other reason),I want to define navigation property relationship without setting foreign key in database? 由于FK的性能较低(和其他原因),我想在不设置数据库外键的情况下定义导航属性关系吗? Delete FK after EF created it? EF创建后删除FK吗? If cannot do this using fluent api, could you tell me why EF designed in this way please? 如果使用流利的api无法做到这一点,您能告诉我为什么EF以这种方式设计吗?

About the lower performance of FK. 关于FK的性能较低。 I have a User table with 5 Million records in it. 我有一个用户表,其中有500万条记录。 when I insert a Question into db, since the db check the question.CreatorId validation from User table, it always slower than without FK. 当我将一个Question插入db时,由于db从User表中检查了question.CreatorId验证,因此它总是比没有FK时慢。 And there are many other reasons that I need to remove FK. 还有许多其他原因需要删除FK。

I think I am somewhat obsession because I think that deleting FK after created it is strangely and ugly. 我认为我有些执迷,因为我认为创建FK后删除FK既奇怪又丑陋。 What i want is implementing this by using something like WithoutForeignKey in fluent api: 我想要的是通过在流畅的api中使用WithoutForeignKey之类的东西来实现这一点:

this.HasRequired(v => v.Creator).WithMany(v => v.Questiones)
.WithoutForeignKey(v => v.CreatorId).WillCascadeOnDelete(false); 

Without questioning why are you trying to do this strange thing and going just to the answer: you could delete fk constraint after generated, or you could use migrations and remove FK generation from the migration code. 不用怀疑为什么要尝试做这个奇怪的事情,而只回答一个问题:您可以在生成后删除fk约束,也可以使用迁移并从迁移代码中删除FK生成。

SQL code generated when traversing nav properties will work even if fk constraint doesn't exist, except for cascade deleting 即使不存在fk约束,遍历导航属性时生成的SQL代码也可以使用,除了级联删除

If you want a relationship between two tables, you need to define a foreign key. 如果要在两个表之间建立关系,则需要定义一个外键。 No way around it. 没办法。 Even if you use Map() in fluent api, you can only hide the foreign key in your model, in the background EF will still use it and it will exist in the database. 即使您在流利的api中使用Map() ,也只能在模型中隐藏外键,在后台EF仍会使用它,并且它会存在于数据库中。

Also I don't get what you mean by "performance" of foreign key? 另外,我不明白外键的“性能”是什么意思? One extra (likely small) column won't make a difference. 额外的一列(可能很小)不会产生任何影响。 If you mean the navigation properties for the performance part, you can do 3 things: 如果您指的是性能部分的导航属性,则可以做三件事:

  1. Don't include them in your model 不要在模型中包含它们
  2. Make them non-virtual to disable lazy loading 使它们成为非虚拟的以禁用延迟加载
  3. Disable lazy loading all together with ctx.Configuration.LazyLoadingEnabled = false; ctx.Configuration.LazyLoadingEnabled = false;一起禁用所有延迟加载ctx.Configuration.LazyLoadingEnabled = false;

If you don't want to tell db about relation and treat both entities as not related (I wonder why), then just ignore these navigation properties and FK field. 如果您不想告诉db有关关系并将两个实体都视为不相关(我想知道为什么),那么只需忽略这些导航属性和FK字段即可。 Note that you will be responsible for managing related entities: saving and loading them from db, updating ids etc 请注意,您将负责管理相关实体:从数据库保存和加载它们,更新ID等

this.Ignore(q => q.Creator);
this.Ignore(q => q.CreatorId);

And you also need to ignore other side of relation, otherwise EF will generate FK column with default name Creator_CreatorId . 而且您还需要忽略关系的另一面,否则EF会使用默认名称Creator_CreatorId生成FK列。 So in Creator entity configuration: 因此,在Creator实体配置中:

this.Ignore(c => c.Questiones);

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

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