简体   繁体   English

映射到 EF Core 中多个表的单个查找表

[英]Mapping To a Single Lookup Table For Multiple Tables in EF Core

I'm attempting to map to a lookup table that contains values for multiple tables.我正在尝试将 map 查找到包含多个表的值的查找表。 I cannot modify the database.我无法修改数据库。 The table has a one-to-many relationship with multiple tables, but no foreign key constraints.该表与多个表具有一对多的关系,但没有外键约束。 The lookup table has three columns code , category and description .查找表包含三列codecategorydescription A sample set of the data would look like this:数据样本集如下所示:

Lookup table:查找表:

code代码 category类别 description描述
1 1 Role角色 Admin行政
2 2 Role角色 User用户
1 1 Job工作 Mechanic机械
2 2 Job工作 Plumber水管工
3 3 Job工作 Electrician电工
1 1 Activity活动 Work工作
2 2 Activity活动 Overtime随着时间的推移
3 3 Activity活动 Training训练

I'm interested in joining the Activity table that looks like this (some columns omitted for clarity):我有兴趣加入看起来像这样的Activity表(为清楚起见,省略了一些列):

Activity table:活动表:

id ID code代码 hours小时
1 1 1 1 8.0 8.0
2 2 1 1 8.0 8.0
3 3 2 2 1.0 1.0
4 4 2 2 5.3 5.3

I want to join the Activity table to the Lookup table using EF Core.我想使用 EF Core 将Activity表加入到Lookup表中。 If I was writing a SQL statement I'd just have something like this:如果我正在写一个 SQL 语句,我只会有这样的东西:

SELECT *
FROM Activity 
JOIN Lookup ON Lookup.code = Activity.code
            AND Lookup.category = 'Activity'

So in EF Core I created my classes to represent my tables:因此,在 EF Core 中,我创建了我的类来表示我的表:

public class Lookup 
{
    [Key]
    public string Code { get; set; }
    public string Category { get; set; }
    public string Description { get; set; }
}

public class Activity 
{
    [Key]
    public string Id { get; set; }
    public string Code { get; set; }
    public double Hours { get; set; }

    [NotMapped]
    public string LookupCategory { get; set; } = "Activity";
    public Lookup ActivityType { get; set; }
}

I also have the following fluent relationship setup:我也有以下流畅的关系设置:

modelBuilder.Entity<Activity>()
    .HasOne<Lookup>(x => x.ActivityType)
    .WithMany()
    .HasForeignKey(x => x.Code);

But this doesn't work since there are multiple rows with the same code value.但这不起作用,因为有多行具有相同的code值。 How do I get the key constraint to also take in to account the LookupCategory value since it is not mapped?由于未映射,如何让键约束也考虑到LookupCategory值?

Look at setting up a Table-Per-Hierarchy, TPH, with Category as the discriminator.看看设置一个 Table-Per-Hierarchy,TPH,用 Category 作为鉴别器。 Then your EF model can have Lookup as the base table, with RoleType, ActivityType, etc. as child entities in your EF model.然后,您的 EF model 可以将 Lookup 作为基表,并将 RoleType、ActivityType 等作为 EF model 中的子实体。 The relationship would be from ActivityType to Activity, and EF would already know that the only applicable values in ActivityType are the Lookup rows with Category = 'Activity'.该关系将从 ActivityType 到 Activity,并且 EF 已经知道 ActivityType 中唯一适用的值是 Category = 'Activity' 的查找行。 You would want to verify all existing data meets those constraints since they aren't enforced in the database.您需要验证所有现有数据是否满足这些约束,因为它们并未在数据库中强制执行。

Following pjs's suggestions I was able to implement the following successfully:按照 pjs 的建议,我能够成功实现以下内容:

I created a new class that extended Lookup .我创建了一个扩展Lookup的新 class 。 This class has the attribute NotMapped , which was an important part in getting everything to finally work.这个 class 具有NotMapped属性,这是让一切最终正常工作的重要部分。

[NotMapped]
public class ActivityType : StaffLookup{ }

In Activity I modified the class to use ActivityType instead of StaffLookup .Activity中,我修改了 class 以使用ActivityType而不是StaffLookup I also removed the LookupCategory property我还删除了LookupCategory属性

public class Activity 
{
    [Key]
    public string Id { get; set; }
    public string Code { get; set; }
    public double Hours { get; set; }

    // This is mapped to our subclass so that we can get the filtered values
    public ActivityType ActivityType { get; set; }
}

In my OnModelCreating I removed the existing fluent relationship added the following new ones:在我的OnModelCreating中,我删除了现有的流畅关系,添加了以下新关系:

// This tells EF what column is used as a the filter
modelBuilder.Entity<StaffLookup>()
    .HasDiscriminator(x => x.Category);

// This is what filters the Lookup table for us
modelBuilder.Entity<ActivityType>()
    .HasDiscriminator()
    .HasValue("Activity");

// Since the foreign key isn't mapped in the database 
// we need to add this relationship
modelBuilder.Entity<ActivityMain>()
    .HasOne(x => x.ActivityType)
    .WithMany()
    .HasForeignKey(x => x.ActivityCode);

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

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