EF4 (CPT5) ForeignKeyAttribute в базовом классе - Assert Failure entityType! = Null - PullRequest
1 голос
/ 16 января 2011

Получение ошибки при попытке установить атрибут ForeignKeyAttribute в базовом классе

class User { }

abstract class FruitBase
{    
   [ForeignKey("CreateById")]
   public User CreateBy{ get; set; }

   public int CreateById{ get; set; }     
}

class Banana : FruitBase { }

class DataContext : DbContext
{    
   public DbSet<Banana> Bananas { get; set; }
}

Если я перенесу код FruitBase в банан, все будет хорошо, но я не хочу этого, потому что будет много фруктов, и я хочу остаться относительно СУХИМ, если смогу

Это известная проблема, которая будет исправлена ​​к марту? Кто-нибудь знает работу вокруг?

Ответы [ 2 ]

2 голосов
/ 16 января 2011

Проблема вызвана тем, что в вашем DbContext вы ставите DbSet<Banana> вместо DbSet<FruitBase>.Следующая объектная модель работает должным образом:

public class User 
{
    public int UserId { get; set; }
}

public abstract class FruitBase
{
    public int Id { get; set; }
    public int CreateById { get; set; }

    [ForeignKey("CreateById")]
    public User CreateBy { get; set; }
}

public class Banana : FruitBase { }

public class DataContext : DbContext
{        
    public DbSet<FruitBase> Fruits { get; set; }                
}

Вы должны знать, что, делая это, вы по существу создаете Полиморфная ассоциация и начиная с CTP5 не все стратегии отображения наследования допускают полиморфную ассоциацию.Здесь все работает нормально, потому что вы использовали Таблица на иерархию (TPH) .

Обновление: использование Таблица для каждого типа (TPT) Стратегия:

Полиморфные ассоциации также работают с TPT:

public class StackoverflowTestContext : DbContext
{
    public DbSet<FruitBase> Fruits { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Banana>().ToTable("Bananas");
    }         
}
0 голосов
/ 17 января 2011

как обсуждалось выше, это TPC ( Таблица для конкретного типа ), ответ / обходной путь заключается в том, чтобы извлечь атрибут ForeignKeyAttribute из базы

class User{}

abstract class AuditObjectBase{ // was FruitBase

   // [ForeignKey("CreateById")]
   public abstract User CreateBy{ get; set; } // made abstract

   public int CreateById{ get; set; } // both get and set required public

}

class ItemOne : AuditObjectBase{ // Was Banana

   // added
   [ForeignKey("CreateById")]
   public override User CreateBy{ get; set; }
}

class ItemTwo : AuditObjectBase{ // Added

   [ForeignKey("CreateById")]
   public override User CreateBy{ get; set; }
}

class DataContext : DbContext{

   DbSet<ItemOne> ItemOnes{ get; set; }
   DbSet<ItemTwo> ItemTwos{ get; set; }
}

Не полностью СУХОЙно, по крайней мере, когда вы создаете объект, который использует AuditObjectBase, он заставит вас реализовать свойство Foreign Key, некоторые приятные комментарии, чтобы напомнить вам об атрибуте, и вы сразу же уйдете

По сути, он выглядит, атрибуты должны быть добавленыдля класса, объявленного в DbContext как Entity, в этом случае имеет свойство DbSet.

...