我正在为我的项目使用Entity Framework 6 Code First。 实体具有继承性,因此我关注的是TPH(每个层次结构的表)。 我阅读了Article和其他很多文章。
他们都没有解释我可以使用映射到基本实体中属性的现有数据库列作为鉴别器的方法。
基于下面的示例,我得到以下异常
在模型生成过程中检测到一个或多个验证错误:
TaskType:名称:类型中的每个属性名称必须唯一。属性名称'TaskType'已经定义。
我认为EF的自动生成的鉴别器和我的实体映射存在冲突。
是否有一种方法可以指示EF不要自动生成列并使用实体映射列。 如果没有,是否有任何无法避免的解释。
和平。
我有以下格式的实体
public enum TaskType
{
Random = 0,
Polished = 1,
Dropping = 2
}
public interface ITask
{
int Id { get; set; }
string Name { get; set; }
TaskType typeofTask { get; set; }
}
public abstract class BaseTask : ITask
{
public BaseTask(string name, TaskType type)
{
this.Name = Name;
this.typeofTask = type;
}
public int Id { get; set; }
public string Name { get; set; }
public TaskType typeofTask { get; set; }
}
public class RandomTask : BaseTask
{
public RandomTask() : base("My Random", TaskType.Random)
{
}
public int Owner { get; set; }
}
public class PolishedTask : BaseTask
{
public PolishedTask() : base("My Polished", TaskType.Polished)
{
}
}
public class DBContextTest : DbContext
{
public DBContextTest(string connection) : base(connection)
{
}
public DbSet<BaseTask> Task { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BaseTask>().Map<RandomTask>(m => m.Requires("TaskType").HasValue(1))
.Map<PolishedTask>(m => m.Requires("TaskType").HasValue(1));
modelBuilder.Entity<BaseTask>().Property(p => p.typeofTask).HasColumnName("TaskType");
}
}
class Program
{
static void Main(string[] args)
{
try
{
DBContextTest dataContext = new DBContextTest("Server = (localdb)\\mssqllocaldb;DataBase = LOC2;Trusted_Connection = True;");
RandomTask randomtask = new RandomTask();
PolishedTask polishedTask = new PolishedTask();
dataContext.Task.Add(randomtask);
dataContext.Task.Add(polishedTask);
dataContext.SaveChanges();
}
catch (System.Exception ex)
{
}
}
}
答案 0 :(得分:1)
从您的实体中删除TaskType,并让EF作为TPH映射的一部分对其进行管理。如果要处理基类集合,则要区分类型,请使用.OfType<PolishedTask>()
而不是.Where(x => x.TaskType == TaskType.Polished)
EF应该照顾其余的情况。如果确实要在实体上使用它,请在子类中创建一个非映射属性。
即
public abstract class BaseTask
{
[NotMapped]
public abstract TaskType TaskType { get; }
}
public class PolishedTask
{
[NotMapped]
public override TaskType TaskType => TaskType.Polished
// or
//public override TaskType TaskType
//{
// get { return TaskType.Polished; }
//}
}