我正在使用每层次表(TPH)。 例如,我们为所有实体都有一个基类:
public abstract class Entity
{
public virtual int Id { get; set; }
public virtual bool IsTransient()
{
return Id == default(int);
}
}
以及几种权利的基类:
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
方法中):序列没有元素
我认为是因为数据库中没有Film
表。如何解决这个问题?
答案 0 :(得分:3)
我没有在您显示的存储库中看到GetEntityName
的需要。对于GetQuery
,您可以直接使用DbContext
API,而无需访问基础ObjectContext
或MetadataWorkspace
:
public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
return DbContext.Set<TEntity>();
}
这会返回DbSet<TEntity>
(IQueryable<TEntity>
)。如果TEntity
派生但MSDN documentation about DbSet<TEntity>
说:“类型可以是派生类型和基类型。”我不是100%确定是否也有效。“所以,我希望也允许Set<TEntity>()
方法用于派生类型。