Sto usando Entity Framework 6 Code First per il mio progetto. Le entità hanno Ereditarietà, quindi seguo TPH (Tabella per Gerarchia). Ho letto l' articolo seguente e molti altri.
Nessuno di loro spiega un modo in cui posso utilizzare una colonna DB esistente mappata a una proprietà in Base Entity come Discriminator.
In base all'esempio seguente, ricevo l'eccezione seguente
Uno o più errori di convalida sono stati rilevati durante la generazione del modello:
TaskType: Nome: ogni nome di proprietà in un tipo deve essere univoco. Il nome della proprietà 'TaskType' è già definito.
Penso che il generatore automatico di EF generato da Discriminator e il mio mapping di entità sia in conflitto.
Esiste un modo possibile per indicare a EF di non generare automaticamente la colonna e utilizzare la colonna mappata sull'entità. In caso contrario, c'è qualche spiegazione di questo non può essere evitato.
Pace.
Ho Entità nel seguente formato
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)
{
}
}
}
Rimuovi TaskType dalla tua entità e lascia che EF lo gestisca come parte della mappatura TPH. Per differenziare i tipi se hai a che fare con una raccolta di classe base, usa .OfType<PolishedTask>()
piuttosto che .Where(x => x.TaskType == TaskType.Polished)
EF dovrebbe occuparsi di tutto il resto. Se lo vuoi sull'entità, crea una proprietà non mappata nelle sottoclassi. 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; }
//}
}