Вы не можете получить RfiMapping
из ContextEntityConfiguration<Rfi>
. Это будет означать, что вы пытаетесь настроить, например, свойство Id
в своем классе Rfi
. При добавлении в конфигурацию модели в основном это выглядит так:
modelBuilder.Entity<Rfi>()
.HasKey(r => r.Id);
// etc.
Но Id
объявляется объявленным в базовом классе Entity
, поэтому вы не можете определить сопоставления для такого свойства в производной сущности. Это то, что говорит исключение.
Если вы хотите определить сопоставления для свойств базового класса, вы также должны использовать этот класс в вашей конфигурации сопоставления:
modelBuilder.Entity<Entity>()
.HasKey(r => r.Id);
// etc.
Я считаю, что общая конфигурация, полученная из EntityTypeConfiguration<TEntity>
, - плохая идея. Производные классы конфигурации должны всегда иметь дело с одной конкретной сущностью (также может быть абстрактной сущностью) и определять сопоставления для нее.
Итак, у вас должны быть следующие конфигурации:
public class EntityConfiguration : EntityTypeConfiguration<Entity>
public class ContextEntityConfiguration : EntityTypeConfiguration<ContextEntity>
public class DocumentConfiguration : EntityTypeConfiguration<Document>
public class RfiConfiguration : EntityTypeConfiguration<Rfi>
Редактировать
Вот пример приложения, которое показывает, что оно также не может работать с вашим старым отображением (без ContextEntity
). Вы можете проверить и сравнить различия с вашей реальной моделью. Должно быть какое-то важное отличие, потому что вы говорите, что ваша старая модель работает. Я опустил несколько скалярных свойств, чтобы упростить пример.
- Создание нового консольного приложения .NET 4 в VS2010
- Добавить ссылку на
EntityFramework.dll
- Удалите содержимое
Program.cs
и вставьте следующее
- Запустить приложение (оно вылетит)
->
using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
namespace EFWrongMapping
{
public abstract class Entity
{
public virtual Guid Id { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateModified { get; set; }
}
public abstract class Document : Entity
{
public string Name { get; set; }
}
public class Rfi : Document
{
public string Number { get; set; }
public string Subject { get; set; }
}
public class EntityConfiguration<TEntity> : EntityTypeConfiguration<TEntity>
where TEntity : Entity
{
protected EntityConfiguration()
{
// The following is not allowed if TEntity is Rfi or generally any other
// type than Entity (which makes it useless to create a generic configuration)
HasKey(e => e.Id);
Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
public class RfiMapping : EntityConfiguration<Rfi>
{
public RfiMapping()
{
}
}
public class MyContext : DbContext
{
public DbSet<Entity> Entities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new RfiMapping());
}
}
class Program
{
static void Main(string[] args)
{
using (var context = new MyContext())
{
// just try to build model and initialize DB
var initializer = new DropCreateDatabaseIfModelChanges<MyContext>();
try
{
initializer.InitializeDatabase(context);
}
catch (Exception e)
{
// We will land here with exception:
// "The property 'Id' is not a declared property on type 'Rfi'"
throw;
}
}
}
}
}