У меня есть интересная проблема с EF. Все мои модели наследуются от EntityBase
public abstract class EntityBase
{
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public virtual int Id { get; set; }
}
Id является виртуальным, потому что на некоторых моделях мне нужно было перезаписать атрибуты. Тем не менее, у меня есть одна модель, которая нуждается в перечислении как id.
internal class Katalog : EntityBase
{
[Key]
[Column(Order = 0)]
public new EKatalog Id { get { return (EKatalog)base.Id; } set { base.Id = (int)value; } }
////EKatalog IKatalog.Id => throw new System.NotImplementedException();
////public override int Id { get => base.Id; set => base.Id = value; }
}
В этом созвездии я получаю AmbigiousMatchException от EF (это происходит из Type.GetProperty. Если это обнаруживает более одного, это исключение выдается).
Поэтому я попытался перенастроить базовое свойство в OnModelCreating
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Types().Where(t => t == typeof(Katalog)).Configure(c =>
{
//var properties = c.ClrType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.Name == "Id");
//PropertyInfo propIdKatalog = c.ClrType.GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); // .Where(p => p.Name == "Id");
//PropertyInfo propIdBase = c.ClrType.GetProperties(BindingFlags.Public | BindingFlags.Instance).First(p => p.Name == "Id" & p.DeclaringType == typeof(EntityBase));
////propIdBase.CustomAttributes.
//ConventionPrimitivePropertyConfiguration propConfigBase = c.Property(propIdBase);
//propConfigBase.HasColumnAnnotation("NotMapped", new NotMappedAttribute());
//var propConfig = c.Property(propIdKatalog);
//propConfig.HasColumnOrder(0);
//propConfig.IsKey();
});
////var converter = new ValueConverter<Katalog>();
//modelBuilder.Entity<Katalog>().Ignore(x=>x.)
////modelBuilder.Entity<Katalog>().Map(m =>
////{
//// m.MapInheritedProperties().Property(x => x.Id).HasColumnAnnotation()
//})
}
Я прокомментировал все свои идеи, потому что на самом деле ничего не работает. Что мне нужно, это исключительно в этом типе, чтобы не отображать столбец базового идентификатора. В Katalog мне нужно свойство enum id.
РЕДАКТИРОВАТЬ 1:
проверив ответ, я узнал, что проблема возникла в Seed-Method. У меня было это Семя:
protected override void Seed(EFOverwriteIntEnum.ApplicationContext.DatabaseContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
#region Katalogeinträge
List<Katalog> katalogEntry = new List<Katalog>
{
new Katalog
{
Id = EKatalog.BeiratWert, Theme = "BeiratWert"
},
new Katalog
{
Id = EKatalog.BringungWert, Theme = "BringungWert"
},
};
foreach (var entry in katalogEntry)
{
// context.Katalog.AddOrUpdate(entry); // AmbigiousMatchException - bug in DbSetMigrationsExtensions.AddOrUpdate
context.Katalog.Add(entry);
context.SaveChanges();
}
#endregion
}
Я использовал метод AddOrUpdate из DbSetMigrationsExtensions, как это рекомендуется в сгенерированном комментарии. Но особенно в этом случае есть ошибка. Если я использую обычный метод Add и SaveChanges, он работает.
Спасибо за помощь. Я отмечу данный ответ как ответ, потому что он указал мне правильное направление.
Nico