Come rendere OBBLIGATORIO facoltativo per lo stesso attributo su diverse classi ereditate su EF6.
Perché l''attributo obbligatorio' di un bambino è richiesto per un altro bambino? Perché il framework di entità unisce tutte le anotazioni di dati alla classe di base "Persona" se la classe di base non è attributi obbligatori?
Ho usato le stesse classi su MVC per creare campi obbligatori su cshtml e funziona. L'MVC comprende solo il campo obbligatorio di un bambino e non crea alcuna "unione errata" con quelle due classi secondarie.
Per esempio:
//EF Codefirst Class
public class Person
{
[Key]
public int key{get;set;}
[StringLength(500)]
public virtual string name { get; set; }
[StringLength(500)]
public virtual string email{ get; set; }
[StringLength(500)]
public virtual string phone{ get; set; }
[StringLength(500)]
public virtual string address{ get; set; }
[StringLength(500)]
public virtual string manager{ get; set; }
[StringLength(500)]
public virtual string Discriminator{ get; set; }
}
//My Inherited classes
public class Employee : Person
{
[Required]
public override string name{ get; set; }
[Required]
public override string phone{ get; set; }
[Required]
public override string manager{ get; set; }
}
public class Manager: Person
{
[Required]
public override string name{ get; set; }
[Required]
public override string email{ get; set; }
}
//And my sample function 'Add PersonManager'
private void InsertPerson()
{
using (var ctx = new MyDataContext())
{
try
{
var m = new Manager() ;
m.name = "my name" ;
m.email = "my@email.com";
m.address =" something";
ctx.Person.Add(m);
ctx.SaveChanges();
}
catch (Exception ex)
{
// Why, if I try to Add my Person 'Manager', the attribute : phone and manager is REQUIRED?
}
}
}
Succede perché stai usando la strategia TPH. Tutte le entità saranno unite in una tabella, EF gestisce ciò che deve essere nullo o non nullo.
Se si utilizza la strategia TPT, EF creerà tabelle diverse per ciascuna entità. Per saperne di più sulle strategie di ereditarietà, dai un'occhiata a questo link http://blogs.msdn.com/b/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx
Per utilizzare TPT al posto di TPH, è necessario definire una "chiave" nella classe figlia, in questo modo:
public class Employee : Person
{
[Key]
public int employeeId;
[Required]
public override string name;
[Required]
public override string phone;
[Required]
public override string manager;
}
Un altro modo per farlo è utilizzare l'API Fluent. Come questo:
modelBuilder.Entity<Person>()
.HasKey(c => c.key);
modelBuilder.Entity<Employee>()
.ToTable("Employees");
modelBuilder.Entity<Manager>()
.ToTable("Managers");
Per ulteriori informazioni, consultare questo link https://msdn.microsoft.com/en-us/data/jj591617.aspx#2.5