我有一个客户列表,可以根据用户的选择从1到6个字段中进行排序.排序字段可以按任何顺序排列.如果我提前知道字段和序列,则排序很容易:
customers = customers
.OrderBy(c => c.LastName)
.ThenBy(c => c.City)
.ThenBy(c => c.Age).ToList();
Run Code Online (Sandbox Code Playgroud)
我如何在运行时传递排序字段?有没有办法做这样的事情?
string sortField1 = "State";
string sortField2 = "City";
string sortField3 = "Type";
customers = customers
.OrderBy(c => c.sortField1)
.ThenBy(c => c.sortField2)
.ThenBy(c => c.sortField3).ToList();
Run Code Online (Sandbox Code Playgroud) 我正在处理用户可以选择他/她想要在屏幕上看到的列以及要分组或聚合的列的应用程序.因此,在我的LINQ部分中,我实际上应该将包含列名的变量传递给group by和aggregate子句.请记住,DataTable dt每次可能包含不同的数据(例如员工信息,采购订单,绩效统计等).我只能通过dt.Columns[i].ColumnName和运行时获取有关数据的信息dt.Columns[i].DataType.Name.任何人都可以建议如何做到这一点,我需要的是这样的事情:
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
var query = from row in dt.AsEnumerable()
group row by new
{
foreach(DataColumn column in dt.Columns)
{
row[column.ColumnName];
}
} into grp
select new
{
foreach(DataColumn column in dt.Columns)
{
if(column.DataType.Name == "Decimal")
{
Sum(grp[column.ColumnName]);
}else{
grp[column.ColumnName];
}
}
};
Run Code Online (Sandbox Code Playgroud) 我尝试动态创建一些LINQ查询来搜索所有列中的数据.

目前,我使用以下代码来构建动态LINQ查询.然而,当处理复杂的列时,它是非常错误的.
var type = property[col.ToLower()].PropertyType;
var isNullableType = type.IsGenericType && type.GetGenericTypeDefinition() == typeof (Nullable<>);
if (type.IsValueType && !isNullableType)
{
filter += col + ".ToString().ToLower().Contains(@" + i + ".ToLower())";
}
else if (isNullableType)
{
filter += col + ".HasValue ? " + col + ".Value.ToString().ToLower().Contains(@" + i + ".ToLower())" + " : false";
}
else
{
filter += "(" + col + " != null ? " + col + " : \"\").ToString().ToLower().Contains(@" + i + ".ToLower())";
}
Run Code Online (Sandbox Code Playgroud)
你有什么想法来简化我的上述代码吗?如果您的建议仅适用于SQL Server …
如何使用Dynamic Linq库(System.Linq.Dynamic)构建以下LINQ查询?
var roles = rolesCollection.Where(r => r.AssignedUsers.Where(u => u.Name.FirstName == "Patrick").Count() > 0);
Run Code Online (Sandbox Code Playgroud)
rolesCollection和AssignedUsers是实现IEnumerable接口的集合.
我在考虑做这样的事情:
rolesCollection.Where("AssignedUsers.Where(\"Name.FirstName == 'Patrick'\").Count() > 0");Run Code Online (Sandbox Code Playgroud)
但这不起作用.抛出一个ParseException,其中包含消息"无适用的聚合方法'在哪里'存在".
提前致谢.
我在IQueryable上有一个扩展,允许传递分隔的属性名称字符串,当使用时会导致查询不构造JOIN并有效地导致SELECT N + 1问题.
我注意到的是,如果我直接从DbSet调用本机EF扩展名.Include("property"),一切正常.但是,如果我使用我的扩展(我甚至简化它只是调用.Include("property")SELECT N + 1发生...
我的问题是为什么?我究竟做错了什么?
这是调用方法(来自服务)
public MyModel[] GetAll(int page, out int total, int pageSize, string sort, string filter)
{
return _myModelRepository
.Get(page, out total, pageSize, sort, filter, "PropertyOnMyModelToInclude")
.ToArray();
}
Run Code Online (Sandbox Code Playgroud)
这是使用扩展的存储库方法
public virtual IQueryable<T> Get(int page, out int total, int pageSize, string sort, string filter = null, string includes = null)
{
IQueryable<T> query = DatabaseSet;
if (!String.IsNullOrWhiteSpace(includes))
{
//query.IncludeMany(includes); // BAD: SELECT N+1
//query.Include(includes); // BAD: SELECT N+1
}
if (!String.IsNullOrWhiteSpace(filter))
{
query.Where(filter);
} …Run Code Online (Sandbox Code Playgroud) 假设我已经定义了以下变量:
IQueryable<MyClass> myQueryable;
Dictionary<string, Expression<Func<MyClass, bool>>> extraFields;
// the dictionary is keyed by a field name
Run Code Online (Sandbox Code Playgroud)
现在,我想将一些动态字段添加到IQueryable中,以便它返回一个IQueryable<ExtendedMyClass>,其中ExtendedMyClass定义为:
class ExtendedMyClass
{
public MyClass MyObject {get; set;}
public IEnumerable<StringAndBool> ExtraFieldValues {get; set;}
}
class StringAndBool
{
public string FieldName {get; set;}
public bool IsTrue {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
换句话说,对于每个值extraFields,我希望有一个值来ExtendedMyClass.ExtraFieldValues表示该表达式是否为该行的计算结果为True.
我有一种感觉,这应该在动态的Linq和LinqKit中可行,尽管我以前从未认真对待过.我也对其他建议持开放态度,特别是如果这可以通过良好的"强力型Linq"来完成.
我正在使用Linq to Entities,因此查询需要转换为SQL.
使用System.Linq.Dynamic(在这里管理https://github.com/kahanu/System.Linq.Dynamic),我试图使用Entity Framework 6(或更高版本)捕获在聚合目的DayOfWeek上找到的字段DateTime.
以前要求类似的东西,这有很大帮助,动态Linq +实体框架:动态选择的日期时间修改
实体框架支持DayOfWeek使用
SqlFunctions.DatePart("dw", datetime?)
Run Code Online (Sandbox Code Playgroud)
或者我们可以用类似的东西做一些更需要的东西
DbFunctions.DiffDays(date?, date?).
Run Code Online (Sandbox Code Playgroud)
理念:
我发现这非常有趣,我喜欢它,因为它不使用SqlFunctions可能让我局限于SQL Server的东西.此外,开发人员可以控制一周的第一天,而无需查询SQL Server属性以查找其配置方式(第一天).
出于实验目的,我一直试图在VisitMember()覆盖中实现这一点:
protected override Expression VisitMember(MemberExpression node)
{
if (node.Type == typeof(System.DayOfWeek))
{
var firstSunday = new DateTime(1753, 1, 7);
var firstSundayExpression = Expression.Constant(firstSunday, typeof(DateTime?));
var timeValue = node.Expression;
if (timeValue.Type != typeof(DateTime?)) timeValue = Expression.Convert(timeValue, typeof(DateTime?));
var methodCall = Expression.Call(
typeof(DbFunctions), "DiffDays", Type.EmptyTypes, firstSundayExpression, timeValue);
return Expression.Convert(methodCall, typeof(int?));
} …Run Code Online (Sandbox Code Playgroud) 我在尝试对 Order 表中没有的任何列进行排序时遇到此错误,如果我使用OrderBy("Customer.CompanyName" + " " + sortDir)该错误将消失但所有列都将无法排序。下面OrderBy使用的方法来自这里。
问题的原因是什么?
public ActionResult WebGrid(int page = 1, int rowsPerPage = 10, string sortCol = "OrderID", string sortDir = "ASC")
{
List<Order> res;
using (var nwd = new NorthwindEntities())
{
var _res = nwd.Orders
.OrderBy(sortCol + " " + sortDir)
.Select(o => new Order
{
OrderID = o.OrderID,
OrderDate = o.OrderDate,
CompanyName = o.Customer.CompanyName,
FirstName = o.Employee.FirstName,
//......
//......
//......
});
Run Code Online (Sandbox Code Playgroud) 我将 System.Linq.Dynamic.Core 版本 1.0.7.6 与 EF 和 Oracle.ManagedDataAccess.EntityFramework 12.1.2400 一起使用。
知道为什么动态查询像
EntitySet.Where($"Date == @0", date)
Run Code Online (Sandbox Code Playgroud)
被翻译成sql:
SELECT * FROM "Schema"."Entities" "Extent1"
WHERE (TO_TIMESTAMP('2016-02-12 00:00:00.000', 'YYYY-MM-DD HH24:MI:SS.FF') = "Extent1"."Date")
Run Code Online (Sandbox Code Playgroud)
注意TO_TIMESTAMP函数调用。
而在相同上下文和相同集合上进行标准 Linq 查询
EntitySet.Where(p => p.Date == date)
Run Code Online (Sandbox Code Playgroud)
翻译为:
SELECT * FROM "Schema"."Entities" "Extent1"
WHERE ("Extent1"."Date" = :p__linq__0)
Run Code Online (Sandbox Code Playgroud)
无TO_TIMESTAMP函数调用
我怎么能定义一个where in标准Dynamic Linq?
我厌倦了下面的解决方法,但它一定不起作用,因为它没有意义!
context.Records.Where("@0.Contains(ID)", new object[]{
new string[] {"1", "2", "3"}
}); // throws error No property or field 'ID' exists in type 'String'
Run Code Online (Sandbox Code Playgroud)
编辑1:
感谢大家,您只需要在查询中使用itorouterIt关键字Dynamic.Linq,所以在我的示例中,我只需要使用outerIt:
context.Records.Where("@0.Contains(outerIt.ID)", new object[]{
new string[] {"1", "2", "3"}
});
Run Code Online (Sandbox Code Playgroud)
您可以在此处找到更多示例和信息:高级 Linq - 动态 Linq 查询库:添加对“包含”扩展的支持
dynamic-linq ×10
linq ×8
c# ×7
asp.net-mvc ×2
.net-3.5 ×1
aggregate ×1
group-by ×1
linqkit ×1
objectquery ×1
oracle ×1
sql-server ×1