我怎么能一般地。包括限于某一类的实体的属性?

时间:2014-08-18 19:26:30

标签: c# entity-framework generics func

我正在使用带有T4模板的Entity Framework 6.x从我的DbContext生成我的.edmx和我的实体类。我的所有实体都继承了一个名为BaseEntity的类。以下面的示例实体为例:

public partial class UserEntity : BaseEntity {
    [IdentityColumn]
    public int Id  { get; set; }
    public string Name { get; set; }
    public int fkUserLocationId { get; set; }

    [NavigationColumn]
    public virtual ICollection<UserRole> UserRoles { get; set; }   
    [NavigationColumn]
    public virtual UserLocation UserLocation { get; set; }
}

UserRoleUserLocation也会继承BaseEntity。我有一个通用的存储库接口IGenericRepository<TEntity> where TEntity : BaseEntity和一个GenericRepository<TEntity> where TEntity: BaseEntity的实现:

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : BaseEntity {
    protected readonly MyDbContext _context;
    protected readonly DbSet<T> _dbSet;

    public GenericRepository(MyDbContext context) {
        _context = context;
        _dbSet = context.Set<T>();
    }

    //Would like to limit object to be of type BaseEntity or ICollection<BaseEntity>
    public IQueryable<TEntity> Get(params Expression<Func<TEntity, object>>[] includeProperties)
    {
        var query = _dbSet.AsQueryable();
        foreach (var include in includeProperties){
            query = query.Include(include);
        }

        return query;
    }
}

通过所有这些,我可以通过执行以下操作轻松地包含实体:

//Assume this repository already exists
_userRepository.Get(user => user.UserRoles, user => user.UserLocation); //Valid include
_userRepository.Get(user => user.Name); //Invalid include but appears in Intellisense

如何才能正确定义此方法,即只有BaseEntity属性(或具有NavigationColumn属性的属性)在Func中有效?

1 个答案:

答案 0 :(得分:2)

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : BaseEntity {
    protected readonly MyDbContext _context;
    protected readonly DbSet<T> _dbSet;

    public GenericRepository(MyDbContext context) {
        _context = context;
        _dbSet = context.Set<T>();
    }

    //Would like to limit object to be of type BaseEntity or ICollection<BaseEntity>
    public IQueryable<TEntity> Get(params Expression<Func<TEntity, object>>[] includeProperties)
    {
        var query = _dbSet.AsQueryable();
//Something like that may help? wont solve the issue of intelisense knowing what is allowed and what is not allowed. 

        includeProperties = includeProperties.Where(p=>p.Type.DeclaringType.GetCustomAttributes(typeof(NavigationProperty),true).Any());

        foreach (var include in includeProperties){
            query = query.Include(include);
        }

        return query;
    }
}