2012-11-25 80 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>()方法允許導出類型爲好。