2012-11-25 49 views
0

我使用的表每个层次结构(TPH)。 例如,我们对所有的实体基类:表每个继承和存储库

public abstract class Entity 
    { 
     public virtual int Id { get; set; } 

     public virtual bool IsTransient() 
     { 
      return Id == default(int); 
     } 
    } 

和基类数entitites:

public abstract class Event:Entity 
    { 
     [MaxLength(50)] 
     [Required] 
     public string Name { get; set; } 

     [Required] 
     public string Description { get; set; } 

     [Required] 
     [MaxLength(100)] 
     public string ShortDescription { get; set; } 

     [Required] 
     public DateTime PublishDate { get; set; } 

     public int Duration { get; set; } 
    } 

public class Film:Event 
    { 
     public string Director { get; set; } 

     public string ActorList { get; set; } 

     public override string ToString() 
     { 
      return Name; 
     } 
    } 

public class Concert:Event 
    { 
     public string Genre { get; set; } 

     public override string ToString() 
     { 
      return Name; 
     } 
    } 

我的背景:

public class MyContext:DbContext 
    { 
     public MyContext():base(ConfigurationManager.ConnectionStrings["MyContext"].ConnectionString) 
     { 
     } 

     public DbSet<Event> Events { get; set; } 

     public virtual void Commit() 
     { 
      base.SaveChanges(); 
     } 

    } 

这是基础资源库:

public class GenericRepository : IRepository 
{ 
    //... 

    public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class 
      { 
       return GetQuery<TEntity>().AsEnumerable(); 
      } 

    public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class 
      {   
       var entityName = GetEntityName<TEntity>(); 
       return ((IObjectContextAdapter)DbContext).ObjectContext.CreateQuery<TEntity>(entityName); 
      } 

private string GetEntityName<TEntity>() where TEntity : class 
     { 
      string entitySetName = ((IObjectContextAdapter)DbContext).ObjectContext 
       .MetadataWorkspace 
       .GetEntityContainer(((IObjectContextAdapter)DbContext).ObjectContext.DefaultContainerName, DataSpace.CSpace) 
       .BaseEntitySets.First(bes => bes.ElementType.Name == typeof(TEntity).Name).Name; 

      return string.Format("{0}.{1}", ((IObjectContextAdapter)DbContext).ObjectContext.DefaultContainerName, entitySetName); 
     } 

    } 

接下来,创建上下文和库:

var context = new MyContext(); 
EventRepository repository = new EventRepository(context); 
var films = repository.GetAll<Film>(); 

但我得到异常(在GetEntityName法)中的序列不具有的元素。
我认为这是因为DB中没有Film表。如何解决这个问题呢?

回答

3

我没有看到GetEntityName需要在您显示的存储库中。对于GetQuery你可以直接使用DbContext API并且不需要访问底层ObjectContextMetadataWorkspace

public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class 
{   
    return DbContext.Set<TEntity>(); 
} 

这会返回一个DbSet<TEntity>(这是一个IQueryable<TEntity>)。我不是100%确定,如果这也适用,如果TEntity派生,但MSDN documentation about DbSet<TEntity>说:“该类型可以派生类型以及基类型”所以,我希望Set<TEntity>()方法允许导出类型为好。