【发布时间】:2021-01-26 10:16:35
【问题描述】:
我们有一个使用 .NET Framework 4.5.2 和 Entity Framework 6.2.0 的现有代码优先数据库,其中模型在单独的类库中定义。
DAL 类库定义了自己的模型,继承自通用模型。
在 DAL 模型中,外键是使用 ForeignKey 属性定义的,因为有时无法应用默认命名约定。
我们为导航属性添加了ScriptIgnore 属性以防止出现序列化问题。
一切都按预期工作,除了在添加新迁移时会删除“一些”外键,使用默认命名约定添加新列,并将外键应用于这些新列。
只需删除 ScriptIgnore 属性,迁移就可以了,外键都保持原样。
并非所有外键都以这种方式被删除和重新创建,例如在同一张表上,有 3 个外键并且没有一个遵循命名约定,因此用 ForeignKey 和 ScriptIgnore 属性装饰,但只有其中一个被迁移删除并重新创建。
我们无法弄清楚在哪种情况下ForeignKey 属性不受尊重以及导致这种行为的原因。
public class Alarm
{
// ...
public int? idChannel { get; set; }
public int? idDevice { get; set; }
public int? idScenario { get; set; }
// ...
}
public class EFAlarm : Alarm
{
[ForeignKey("idChannel"), ScriptIgnore]
public virtual EFChannel Channel { get; set; } // This one is kept as is
[ForeignKey("idDevice"), ScriptIgnore]
public virtual EFDevice Device{ get; set; } // This one is kept as is
[ForeignKey("idScenario"), ScriptIgnore]
public virtual EFScenario Scenario { get; set; } // This one is dropped and recreated
}
这里是迁移的摘录:
public override void Up()
{
// ...
DropForeignKey("dbo.fe_alarms", "idScenario", "dbo.scenario");
DropIndex("dbo.fe_alarms", new[] { "idScenario" });
AddColumn("dbo.fe_alarms", "Scenario_id", c => c.Int());
CreateIndex("dbo.fe_alarms", "Scenario_id");
AddForeignKey("dbo.fe_alarms", "Scenario_id", "dbo.scenario", "id");
// ...
}
ScriptIgnore 属性在 System.Web 程序集中定义。 我们尝试使用在不同程序集中定义的其他自定义属性,但似乎没有一个会导致此类问题。 这种行为的原因可能是什么?
【问题讨论】:
-
只是仔细检查:通过删除 ScriptIgnore 属性,迁移是否正确生成?
-
是的,去掉 ScriptIgnore 属性外键是正确的。
-
这些实体其实很大,但最终它们都有一个整数主键和一个属性列表。 FluentAPI 用于其他地方,但不是用于定义那些 ForeignKeys,只是 Channel 具有反向导航属性 HasMany(e => e.Alams).WithOptional(e => e.Channel)
标签: c# entity-framework