Entity Framework Core Database First - Multiple Foreign keys to one table

时间:2018-04-18 17:45:19

标签: c# entity-framework-core asp.net-core-2.0 ef-database-first

Background Information

I am currently working with EF Core using a database first implementation.

Current tables

Fizz
{
    [Id] INT
    [Category] varchar
    [Value] varchar
}

Buzz
{
    [Id] UniqueIdentifier
    [TypeId1] INT
    [TypeId2] INT
    CONSTRAINT [FK_Buzz_Fizz_1] FOREIGN KEY ([TypeId1] REFERENCES [Fizz][Id]) 
    CONSTRAINT [FK_Buzz_Fizz_2] FOREIGN KEY ([TypeId2] REFERENCES [Fizz][Id])
}

Fizz currently acts a lookup table. Doing this allows for a single data repository to be used to find different values by category.

Buzz is a table that has two different type values to be stored e.g. TypeId1 could be brand which would exist in Fizz as (id, Brands, Nestle) and TypeId2 could be a flavor which would exist in Fizz as (id, Flavors, Grape).

The Issue

I scaffold the db to create the Data Models. When running the application the following occurrs:

InvalidOperationException: Unable to determine the relationship represented by navigation property 'Buzz.TypeId1' of type 'Fizz'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

One solution that has occurred to me is to break this lookup table (Fizz) into multiple tables that way the references could be resolved by not having duplicate types used for Foreign Keys.

This would require re-work of the logic for the current data repository to either access multiple tables or be split into multiple data repos.

Another solution would be to modify the DBContext that is generated and use DataAnnotations on the DataModel. I would like to avoid doing this as the Context and Models will be regenerated in the future and these changes will be overwritten.

Is there a way to have a datamodel generated from a table that has multiple Foreign Keys to a single table without having to modify the generated code?

1 个答案:

答案 0 :(得分:2)

后人:

使用数据库方法完成db的脚手架以创建上下文和数据模型。

生成的数据模型(使用上面的示例表)看起来像这样 -

public partial class Buzz
{
    public Buzz()
    { }

    public Guid Id { get; set; }
    public int TypeId1 { get; set; }
    public int TypeId2 { get; set; }

    public Fizz TypeId1Fizz { get; set; }
    public Fizz TypeId2Fizz { get; set; }
}


public partial class Fizz
{
    public Fizz()
    { }

    public int Id { get; set; }
    public string Category { get; set; }
    public string Value { get; set; }

    public ICollection<Buzz> TypeId1Fizz { get; set; }
    public ICollection<Buzz> TypeId2Fizz { get; set; }
}

问题是Buzz中的关系无法解决。

解决方案

在数据库上使用scaffold时,所有模型都将生成为指定文件夹的部分。我在另一个目录中创建了一个部分Buzz类,该目录位于scaffold创建的目录内(确保命名空间匹配VS喜欢将目录名添加到命名空间,并且部分不匹配)。

public partial class Buzz
{
    [NotMapped]
    public Fizz TypeId1Fizz { get; set; }
    [NotMapped]
    public Fizz TypeId2Fizz { get; set; }
}

但是Leustherin然后你失去了利用的能力。包括Fizz! EntityFramework不会为您创建SQL连接语句,因此您必须额外访问数据库才能获得查找值!

要解决此问题,请覆盖数据存储库的Get或GetAll函数并创建自己的join语句。

为什么我选择此解决方案

可维护性。

无论何时重新生成DataModel而不是获取运行时错误,现在都会出现编译错误,提醒开发人员从生成的数据模型中删除额外的属性。

自动生成的文件没有其他修改。

没有进行重大架构更改以适应更改。

我会尽力保持更新。