【问题标题】:EF5 Code first TPH Mapping error using DBSet.Find()EF5 Code first TPH Mapping error using DBSet.Find()
【发布时间】:2012-08-14 13:35:37
【问题描述】:

使用 Entity Framework 5 Code First 时,使用 Table Per Hierarchy。 这与存储库和工作单元相结合(尝试了几种实现)。 我遇到以下错误:

(34,10) : 错误 3032:从第 19、34 行开始映射片段时出现问题:EntityTypes T、T 被映射到表 T 中的相同行。映射条件可用于区分这些类型的行映射到。

我已使用以下指南解决了此问题: Entity Framework 4.3 - TPH mapping and migration error

这在使用所有记录的一般查找时有效,然后没有错误。

使用DBSet<T>.Find(id) 时,我收到上述错误消息。

使用DBSet<T>.Where(t => t.id == id) 时一切正常。

请问有人有解决这个问题的方法吗?

public class TDataContext : DbContext
{
    // Models
    public abstract class BaseTrackable
    {
        public DateTime DateModified { get; set; }
    }

    public abstract class ParentClass : BaseTrackable
    {
        public int ParentId { get; set; }
        public string ParentString { get; set; }
    }

    public class Foo : ParentClass
    {
        public string FooString { get; set; }
    }

    public class Bar : ParentClass
    {
        public string BarString { get; set; }
    }

    // Configuration
    public class ParentConfiguration : EntityTypeConfiguration<ParentClass>
    {
        public ParentConfiguration()
        {
            ToTable("Parent");
        }
    }

    public class FooConfiguration : EntityTypeConfiguration<Foo>
    {
        public FooConfiguration()
        {
            Map(m => m.Requires("FooIndicator").HasValue(true));
        }
    }

    public class BarConfiguration : EntityTypeConfiguration<Bar>
    {
        public BarConfiguration()
        {
            Map(m => m.Requires("BarIndicator").HasValue(true));
        }
    }

    public DbSet<ParentClass> Parent { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations
            .Add(new ParentConfiguration())
            .Add(new FooConfiguration())
            .Add(new BarConfiguration());
    }

}

public class Controller
{
    TDataContext _context = new TDataContext();

    // Repository function
    public T GetById<T>(object id) where T : class 
    {
        var dbset = _context.Set<T>();
        return dbset.Find(id);
    }

    public IQueryable<TDataContext.Foo> GetFiltered(Expression<Func<TDataContext.Foo, bool>> filter) 
    {
        var dbset = _context.Set<TDataContext.Foo>();
        return dbset.Where(filter);
    }

    // Final call
    // Which fails..
    public TDataContext.Foo Get(int id)
    {
        return this.GetById<TDataContext.Foo>(id);
    }

    // This works...
    public TDataContext.Foo GetWhere(int id)
    {
        return this.GetFiltered(f => f.ParentId == id).FirstOrDefault();
    }
}

【问题讨论】:

  • 你能贴一些代码吗?这没有任何问题。看起来并非 TPH 中的所有类型都正确映射到鉴别器值。
  • 在 TPH 中,ParentClass 必须与子表映射到同一个表,并且必须配置鉴别器。
  • 嗨 Ladislav,这是使用 Map(m => m.Requires("Indicator").HasValue(true)) 完成的

标签: entity-framework repository unit-of-work entity-framework-5


【解决方案1】:

不会更好

public class FooConfiguration : EntityTypeConfiguration<Foo> 
{ 
    public FooConfiguration() 
    { 
        Map(m => m.Requires("Type").HasValue("Foo")); 
    } 
} 

public class BarConfiguration : EntityTypeConfiguration<Bar> 
{ 
    public BarConfiguration() 
    { 
        Map(m => m.Requires("Type").HasValue("Bar"); 
    } 
}

通过这种方式,FooConfiguration 不需要了解有关 BarConfiguration 的任何信息,反之亦然。从 EF 4.3 迁移到 5.0 时我遇到了这个问题,我认为改变的是 EF 5.0 中的鉴别器数据库列不可为空。我认为它们不可为空更有意义,一般来说,每个派生类型只有一个鉴别器列而不是每个类型一个列(就像在 EF 4.3 中那样)

-斯坦

【讨论】:

    【解决方案2】:

    找到了可以部分解决我的问题的东西……

    向表格中添加另一个指标时,不再出现错误,例如:

    public class FooConfiguration : EntityTypeConfiguration<Foo>
        {
            public FooConfiguration()
            {
                Map(m => {
                    m.Requires("FooIndicator").HasValue(true);
                    m.Requires("BarIndicator").HasValue<short>(1);
                });
            }
        }
    
        public class BarConfiguration : EntityTypeConfiguration<Bar>
        {
            public BarConfiguration()
            {
                Map(m => {
                    m.Requires("BarIndicator").HasValue(true);
                    m.Requires("FooIndicator").HasValue<short>(0);
                });
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-11
      • 2013-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多