Это скорее мыслящее упражнение, чем что-либо. Рассмотрим следующие классы:Просачивание не работает, когда свойство скрывается
public abstract class Entity : IEntity
{
public object Id { get; set; }
private string name;
[Required]
public string Name
{
get { return name ?? Guid.NewGuid().ToString(); }
set { name = value; }
}
private DateTime? createdDate;
[DataType(DataType.DateTime)]
public DateTime CreatedDate
{
get { return createdDate ?? DateTime.UtcNow; }
set { createdDate = value; }
}
[DataType(DataType.DateTime)]
public DateTime? ModifiedDate { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
[Timestamp]
public Byte[] Version { get; set; }
}
public abstract class Entity<T> : Entity, IEntity<T>
{
[Key]
new public T Id
{
get { return base.Id != null ? (T)base.Id : default(T); }
set { base.Id = value; }
}
}
Entity<T>
скрывает в Id
собственности на Entity
заменив его на правильный тип. Если я создаю объект из этого:
public class Foo : Entity<int>
{
...
}
и добавить его в контекст:
public virtual IDbSet<Foo> Foos { get; set; }
Entity Framework счастливо создает соответствующую таблицу. Все основные функции EF работают нормально: я могу запросить, сохранить, обновлять, удалять и т.д.
Однако, если я пытаюсь семя:
context.Foos.AddOrUpdate(
r => r.Name,
new Foo { ... },
new Foo { ... },
...
);
И запустить update-database
. В первый раз, посев работает правильно. На каждом последующем цикле, однако высев сгенерирует исключение:
Running Seed method.
System.Reflection.AmbiguousMatchException: Ambiguous match found.
at System.Data.Entity.Utilities.TypeExtensions.GetAnyProperty(Type type, String name)
at System.Data.Entity.Migrations.DbSetMigrationsExtensions.<>c__DisplayClass9`1.<GetKeyProperties>b__8(EdmMember km)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](DbSet`1 set, IEnumerable`1 identifyingProperties, InternalSet`1 internalSet, TEntity[] entities)
at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](IDbSet`1 set, Expression`1 identifierExpression, TEntity[] entities)
...
at System.Data.Entity.Migrations.DbMigrationsConfiguration`1.OnSeed(DbContext context)
at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Ambiguous match found.
Теперь я понимаю, почему это происходит. EF использует отражение и получает два результата для Id
, один от Entity
и один от Entity<T>
. Он не может определить, что использовать, и терпит неудачу. Мой вопрос: есть ли что-нибудь, что я могу сделать, чтобы устранить двусмысленность?
Для чего это стоит, я запускаю EF 6.1.3.
никакой другой конфигурации? – jjj
Нет. Это все, что нужно. –
Создана ли таблица, состоящая из двух столбцов Id? – jjj