0

我正在为我的项目使用 Entity Framework 6 Code First。实体具有继承性,因此我遵循 TPH(每个层次结构的表)。我阅读了以下文章和许多其他文章。

他们都没有解释我可以使用映射到基本实体中的属性的现有数据库列作为鉴别器的方式。

根据下面的示例,我得到以下异常

在模型生成期间检测到一个或多个验证错误:

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)
        {

        }

    }
}
4

1 回答 1

1

从您的实体中删除 TaskType 并让 EF 将其作为 TPH 映射的一部分进行管理。如果您正在处理基类集合,为了区分类型,使用.OfType<PolishedTask>()而不是.Where(x => x.TaskType == TaskType.Polished) EF 应该处理其余部分。如果您确实希望在实体上使用它,请在您的子类中创建一个非映射属性。IE

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; }
  //}
}
于 2018-09-24T03:27:36.200 回答