实体框架6数据库优先和外围关键命名约定

时间:2015-08-22 20:29:31

标签: entity-framework entity-framework-6

我们已经开始使用EF6作为重写我们的应用程序套件的一部分。现有套件中有许多完全合理的表,我们使用数据库优先方法重用它们。我的问题是EF6似乎在我的数据库优先模型上执行我认为的代码优先约定。

考虑这个最小的例子,如此定义了两个表,并适当地填充了几行:

CREATE TABLE [dbo].[Table1] (
[Id] INT NOT NULL PRIMARY KEY,
[Table2Reference] INT NOT NULL REFERENCES [dbo].[Table2](Id) )

CREATE TABLE [dbo].[Table2] (
[Id] INT NOT NULL PRIMARY KEY,
[SomeColumn] NVARCHAR(25) )

从数据库运行Update Model后,我们得到了这个模型:

(哎呀。发布图片的声誉不够。这就是你想象的。)

到目前为止一切顺利,但是当您编写代码来访问Table1实体时,就像这样......

var q = _context.Table1.ToList();
foreach (var item in q)
    Debug.WriteLine("{0}", item.Table2Reference);

...它编译得很好,但会抛出ToList()行。这是因为生成的SQL包含对甚至不存在的列的请求:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Table2Reference] AS [Table2Reference], 
[Extent1].[Table2_Id] AS [Table2_Id] <-- this one doesn't exist
FROM [dbo].[Table1] AS [Extent1]

我认为这与外键的代码优先命名约定有关。我知道我可以将Table2的Id列重命名为Table2Id,并将Table2Reference重命名为Table2Id,它将起作用。但是,这应该是数据库优先的。是否有某种方法可以告诉EF不要使用预先定义的数据库中的实际内容?我很早就发现我必须关闭复数约定这个名称,但我似乎无法确定一个关闭修复此问题的约定。我尝试删除这些:

modelBuilder.Conventions.Remove<PrimaryKeyNameForeignKeyDiscoveryConvention>();
modelBuilder.Conventions.Remove<TypeNameForeignKeyDiscoveryConvention>();
modelBuilder.Conventions.Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>();

无论如何,我很难过。是否有一个简单的解决方法,不涉及修改现有数据库?

感谢阅读。

2 个答案:

答案 0 :(得分:0)

您可以使用数据注释属性或Fluent API将EF映射配置为实际的数据库表。以下是如何使用属性:

[Table("Table1")]
public class Table1
{
    public int Id { get; set; }
    public int Table2Reference { get; set; }

    [ForeignKey("Table2Reference")]
    public Table2 Table2 { get; set; }
}

答案 1 :(得分:0)

事实证明,除了拥有EDMX文件之外,数据库优先方法还有一个非常重要的部分。也就是说,您的连接字符串必须包含以下部分:

元数据= RES:// /IPE.csdl|res:// /IPE.ssdl|res://*/IPE.msl; (用您的EDMX的基本名称替换IPE)

否则,EF将无法在程序集中找到EDMX信息,并且代码优先约定可以发挥作用。事情大部分都是有效的,直到他们没有。