将List 转换为EntityFramework列/字段列表

使用EntityFramework,我可以使用以下语法获取特定类型的实体列表:

List customers = ((IQueryable)myEntities.Customers .Where(c => c.Surname == strSurname) .OrderBy(c => c.Surname)).ToList(); 

然后,我可以做这样的事情,最终得到我感兴趣的数据:

 var customerSummaries = from s in customers select new { s.Surname, s.FirstName, s.Address.Postcode }; 

我给出了包含所请求的汇总数据的字段(和必要的表)的string s(基于用户选择)的列表。 例如,对于上面的’customerSummary’,提供的string列表将是:“Surname”,“FirstName”,“Address.Postcode”。

我的问题是:如何将该字符串列表转换为仅提取指定字段所需的语法?

如果无法做到这一点,那么列的列表将是一个更好的类型(比字符串),这样我就可以提取正确的信息?

我想我需要知道EF [entity | table]的[member | column | field]的类型,如果这是有道理的。

编辑:

我尝试了建议的答案 – 动态linq – 使用以下语法

 string parmList = "Surname, Firstname, Address.Postcode"; var customers = myEntities.Customers.Select(parmList) .OrderBy("Address.Postcode"); 

但结果是: EntitySqlException was unhandled. 'Surname' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly. EntitySqlException was unhandled. 'Surname' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly.

所以,一个后续问题。 我正确使用Select吗? 我只看过使用WhereOrderBy子句的例子,但我认为我是基于那些做的正确的。

如果我的Select语法不是问题,任何人都可以看到它是什么?

编辑2:它是颠倒的。 这有效:

 string parmList = "Surname, Firstname, Address.Postcode"; var customers = myEntities.Customers .OrderBy("Address.Postcode") .Select(parmList); 

您可以使用动态linq ,在此处查看 。 它也可以在nuget上使用

我建议@Cuong已发布dynamic linq

但对于简单的Select投影和表达式中的手工练习……

使用 如何创建LINQ表达式树中的 LinqRuntimeTypeBuilder 来选择匿名类型
(见那里的评论’为什么’是必要的)

添加这个 ……

 public static IQueryable SelectDynamic(this IQueryable source, IEnumerable fieldNames) { Dictionary sourceProperties = new Dictionary(); foreach (var propertyPath in fieldNames) { var props = propertyPath.Split('.'); var name = props.Last(); PropertyInfo[] infos; if (sourceProperties.TryGetValue(name, out infos)) name = string.Join("", props); sourceProperties[name] = source.ElementType.GetDeepProperty(props); } Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(sourceProperties.ToDictionary(x => x.Key, x => x.Value.Last().PropertyType)); ParameterExpression sourceItem = Expression.Parameter(source.ElementType, "t"); IEnumerable bindings = dynamicType.GetFields() .Select(p => Expression.Bind(p, sourceItem.MakePropertyExpression(sourceProperties[p.Name]))).OfType(); Expression selector = Expression.Lambda(Expression.MemberInit( Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)), bindings), sourceItem); MethodCallExpression selectExpression = Expression.Call(typeof(Queryable), "Select", new Type[] { source.ElementType, dynamicType }, Expression.Constant(source), selector); return Expression.Lambda(selectExpression).Compile().DynamicInvoke() as IQueryable; } public static PropertyInfo[] GetDeepProperty(this Type type, params string[] props) { List list = new List(); foreach (var propertyName in props) { var info = type.GetProperty(propertyName); type = info.PropertyType; list.Add(info); } return list.ToArray(); } public static Expression MakePropertyExpression(this ParameterExpression sourceItem, PropertyInfo[] properties) { Expression property = sourceItem; foreach (var propertyInfo in properties) property = Expression.Property(property, propertyInfo); return property; } 

使用它像,例如:

 public static IEnumerable SelectAsEnumerable(this IQueryable entitySet, params string[] propertyPath) { return entitySet.SelectDynamic(propertyPath) as IEnumerable; } var list = db.YourEntity.SelectAsEnumerable("Name", "ID", "TestProperty.ID").ToList(); 

注意:
您可以使用类似的方法扩展OrderBy等 – 但这并不意味着涵盖所有角度(或任何真实的查询)

我的这篇文章的 Deep Property Expressions