IQueryable 动态集 属性

IQueryable dynamic set property

从连接表达式

设置谁属性
public interface IHiddenEntity
{
  bool Hidden { get; set;}
}
public interface IEntity 
{
   long Id { get; set;}
   string Name { get; set;}
}

public class Entity: IEntity, IHiddenEntity 
{
   public long Id { get; set;}
   public string Name { get; set;}
   public bool Hidden { get; set;}
}

public class Hidden 
{
   public string TableName {g et; set; }
   public long RecordId { get; set; }
}

public class Person: Entity{ ... }


public IQueryable<T> All(bool loadHidden = false)
  where T : class, IEntity, IHiddenEntity 
{
    string tableName = "<T> name";
    return from x in Context.Set<T>()
           join h in Context.Set<Hidden>().Where(record => record.TableName == tableName) on x.Id equals h.RecordId into hr
            from h_r in hr.DefaultIfEmpty()
            where loadHidden ? true : h_r == null
            select x;
}

但是我不明白如何设置隐藏字段中的值。

  1. 只需要返回IQueryable,因为还有 方法执行的条件。
  2. 也不可能 转换为 IEnumerable:这不是最终值(见上文)。

UDP: 不考虑为每个模型创建选择的选项 - 许多模型具有大量字段!

所以,找到了一个主意。 创建具有所需属性的包装对象并在执行查询后转换为实体类型。

internal EntityWrapper<T>
{
      public T Model { get; set; }
      public bool Hidden { get; set; }
}
public IQueryable<T> All(bool loadHidden = false)
  where T : class, IEntity, IHiddenEntity 
{
    string tableName = "<T> name";
    var query = from x in Context.Set<T>()
           join h in Context.Set<Hidden>().Where(record => record.TableName == tableName) on x.Id equals h.RecordId into hr
            from h_r in hr.DefaultIfEmpty()
            select new EntityWrapper<T>(){ Model = x, Hidden = h_r != null};

    if(!loadHidden)
        query = query.Where(x => !x.Hidden);
}

并在构建 sql 查询和包装对象的结果后进行转换。

    Expression<System.Func<EntityWrapper<T>,T> castFunc = x => x.Select(wr => {wr.Model.Hidden = wr.Hidden; return wr.Model;});

仅投射 IEnumerable<EntityWrapper<T>> 个对象。


var result = castFunc(<query>.ToList());