[c#]通用的 Linq 查询与指定的键获取数组数组的实体

发布时间: 2017/2/28 22:39:27
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

这样的事情需要一个通用的查询,但不能找到任何 web (可能是因为坏搜索 !)

int[] ids = new int[]{1,2,3} 
var q = context.where(o=> ids.contains(o.id));

在其中我实体类型是未知的但我确信︰

  1. 主键是单
  2. 主键类型是int
  3. 不能改变的实体定义

所以签名,有点像这个样子︰

Public IQueryable<T> GetRecords(int[] keys)
{
   var dbset = context.Set<T>();
   ...//the generic query
}

也是重要的泛型和非泛型实现相同的 SQL 输出 (必须具有相同的性能)。

解决方法 1:

private IDictionary<Type, string> _primaryKeyCache = new Dictionary<Type, string>();

public IQueryable<T> GetRecords(int[] keys)
{
   var dbSet = context.Set<T>();

   var type = typeof(T);

   string primaryKeyName;
   if(!_primaryKeyCache.TryGetValue(type, out primaryKeyName)){
      var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
      var set = objectContext.CreateObjectSet<YourEntity>();
      var keyName = set.EntitySet.ElementType
                                            .KeyMembers
                                            .Select(k => k.Name)
                                            .First();

      _primaryKeyCache[type] = primaryKeyName = keyName;
   }

   return dbSet.DynamicContains<T, int>(primaryKeyName, keys);
}

private static IQueryable<T> DynamicContains<T, TProperty>(
        this IQueryable<T> query, 
        string property, 
        IEnumerable<TProperty> items)
    {
        var pe = Expression.Parameter(typeof(T));
        var me = Expression.Property(pe, property);
        var ce = Expression.Constant(items); 
        var call = Expression.Call(typeof(Enumerable), "Contains", new[] { me.Type }, ce, me);
        var lambda = Expression.Lambda<Func<T, bool>>(call, pe);
        return query.Where(lambda);
    }

那应该做你的需要。

赞助商