如何将基本实体字段映射到每个子类

时间:2017-04-06 16:06:44

标签: c# asp.net-core entity-framework-core ef-fluent-api

我有一个基本实体类,我希望能够继承它,这样我只需要为许多不同的特定于实体的存储库编写1 GetById方法。然而," Id"我的一些数据库表中的列必须被调用" Code"由于遗产原因。

我试过(简化版):

public class EntityBase{
    int Id;
}

public class IdEntity : EntityBase{
}

public class CodeEntity : EntityBase{
}

然后在DbContext中:

modelBuilder.Entity<IdEntity>(entity =>
{
    entity.HasKey(e=>e.Id).HasName("PK_IdEntity");
    entity.Property(e=>e.Id).HasColumnName("ID");
}

modelBuilder.Entity<CodeEntity>(entity =>
{
    entity.HasKey(e=>e.Id).HasName("PK_CodeEntity");
    entity.Property(e=>e.Id).HasColumnName("Code"); //this seems to be where it breaks
}

这构建很好,但是当我尝试运行它时,我得到一个InvalidOperationException: 无法为房产调用房产&#39; Id&#39;在实体类型&#39; CodeEntity&#39;因为它被配置为导航属性。属性只能用于配置标量属性。

我试图做的不可能吗?这对我来说似乎不太可能,但那么这样做的正确方法是什么?

编辑:

我实际上试图做的事情比简化的&#34;更复杂。代码我发布在这里。我想这样做,所以我可以有一个字符串或int ID,并使用相同的GetById方法。所以我创建了一个对string和int进行隐式转换的类,我认为这对于Entity Framework是可以的。

不是。

运行时错误是由于尝试告诉EF具有EntityID类型的属性应该是我的密钥,而您不允许这样做。

我无法从Microsoft找到有关Entity Framework中关键值要求的任何文档,但我发现另一个SO问题,即只允许使用标量和字节[] Type safe keys with Entity Framework model

1 个答案:

答案 0 :(得分:1)

我无法获得上面的代码来编译或提供异常,因为在尝试修复它之后你已经足够了。虽然我将描述如何编写您想要实现的场景。

如果要在EF中使用EntityBase作为PK属性,则需要将其设为公共属性。在您的代码中,它是一个私有字段(因为没有get / set方法)。所以你的public class EntityBase { public int Id { get; set; } } 类看起来应该是这样的

OnModelCreating

通过以上更改和GetById代码来映射有问题的实体类型,模型构建正常地创建具有所需表结构和名称的表。

以下是在dbset上实现通用public static T GetById<T>(DbSet<T> dbset, int id) where T : EntityBase { return dbset.FirstOrDefault(e => e.Id == id); } // example var entity = GetById(db.Set<IdEntity>(), 2); 的小方法。它可以成为通用存储库甚至扩展方法的一部分。

inputs