C# 如何将基本实体字段映射到每个子类的不同列
我有一个基本的实体类,我希望能够从中继承,这样我只需要为许多不同的实体特定存储库编写1C# 如何将基本实体字段映射到每个子类的不同列,c#,asp.net-core,entity-framework-core,ef-fluent-api,C#,Asp.net Core,Entity Framework Core,Ef Fluent Api,我有一个基本的实体类,我希望能够从中继承,这样我只需要为许多不同的实体特定存储库编写1GetById方法。但是,出于遗留原因,我的一些数据库表中的“Id”列必须称为“Code” 我试着做(简化版): 然后在DbContext中: modelBuilder.Entity<IdEntity>(entity => { entity.HasKey(e=>e.Id).HasName("PK_IdEntity"); entity.Property(e=>e.Id
GetById
方法。但是,出于遗留原因,我的一些数据库表中的“Id”列必须称为“Code”
我试着做(简化版):
然后在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
}
modelBuilder.Entity(Entity=>
{
entity.HasKey(e=>e.Id).HasName(“PK_标识”);
Property(e=>e.Id).HasColumnName(“Id”);
}
modelBuilder.Entity(Entity=>
{
entity.HasKey(e=>e.Id).HasName(“PK_code实体”);
entity.Property(e=>e.Id).HasColumnName(“代码”);//这似乎是它的断点
}
这构建得很好,但当我尝试运行它时,会出现InvalidOperationException:
无法调用实体类型“CodeEntity”的属性“Id”的属性,因为它已配置为导航属性。属性只能用于配置标量属性
我想做的事情不可能吗?我觉得不太可能,但是正确的方法是什么呢
编辑:
实际上,我试图做的事情比我在这里发布的“简化”代码要复杂得多。我想让它成为一个字符串或int ID,并使用相同的GetById
方法。因此,我创建了一个类,该类隐式转换为字符串和int,我认为这对于实体框架来说是可以的
不是
运行时错误是由于试图告诉EF具有EntityID
类型的属性应该是我的密钥,这是不允许的
我找不到微软关于实体框架中键值要求的任何文档,但我发现了另一个问题,只提到了标量和字节[]允许使用键:我无法编译上述代码或给出异常,因为您在尝试修复后得到的代码已经足够多。不过我将描述如何编写您尝试实现的场景 如果您想在EF中使用
EntityBase.Id
作为PK属性,则需要将其设置为公共属性。在您的代码中,它是一个私有字段(因为没有get/set方法)。因此您的EntityBase
类应该如下所示
public class EntityBase
{
public int Id { get; set; }
}
通过上述更改和OnModelCreating
code映射所发布的实体类型,模型构建可以正确地创建具有所需表结构和名称的表
下面是一个在dbset上实现泛型GetById
的小方法。它可以成为泛型存储库的一部分,甚至是扩展方法
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);
publicstatict GetById(DbSet-DbSet,int-id)
其中T:EntityBase
{
返回dbset.FirstOrDefault(e=>e.Id==Id);
}
//范例
var entity=GetById(db.Set(),2);
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);