表每个继承和存储库

时间:2012-11-25 14:46:24

标签: c# entity-framework

我正在使用每层次表(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表。如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

我没有在您显示的存储库中看到GetEntityName的需要。对于GetQuery,您可以直接使用DbContext API,而无需访问基础ObjectContextMetadataWorkspace

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>()方法用于派生类型。