Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET动态LINQ OrderBy联接和嵌套对象_.net_Linq_Entity Framework_C# 4.0_Dynamic - Fatal编程技术网

.NET动态LINQ OrderBy联接和嵌套对象

.NET动态LINQ OrderBy联接和嵌套对象,.net,linq,entity-framework,c#-4.0,dynamic,.net,Linq,Entity Framework,C# 4.0,Dynamic,我有一个这样的函数- public void ReadTable(string sortField, string sortOrder, string RegID) { sortOrder = sortOrder == "desc" ? "descending" : ""; var db = new MyEntities(); var results = (from CA in db.tblCalifornia join

我有一个这样的函数-

public void ReadTable(string sortField, string sortOrder, string RegID)
{
    sortOrder = sortOrder == "desc" ? "descending" : "";

    var db = new MyEntities();


    var results = (from CA in db.tblCalifornia
                       join BN in db.tblBeach on CA.BeachID equals BN.BeachID into ps
                       from BN in ps.DefaultIfEmpty()
                   where CA.RegID == regID && CA.tblLife.duration != null
                   orderby sortField + " " + sortOrder
                   select new { CA, BN }).ToList();
 }
我想使用tblCalifornia中名为“city”的字段或tblLife中的“duration”字段动态排序

我将函数称为ReadTable(“city”、“asc”、“120”)或ReadTable(“CA.city”、“asc”、“120”)。这两种方法都不起作用,尽管编译是正常的,并且不会引发运行时异常

如何让它工作


谢谢,

您将Linq与带有动态sql的实体混合,这是行不通的。运行时正在根据linq查询构建sql查询,它不知道如何将orderby子句中的原始字符串转换为动态sql

这将使您接近:

var q = (from CA in db.tblCalifornia
           join BN in db.tblBeach on CA.BeachID equals BN.BeachhID into ps
           from BN in ps.DefaultIfEmpty()
           where CA.RegID == regID && CA.tblLife.duration != null
           select new { CA, BN }
        );
if (order == "desc") {
     q = q.OrderByDescending(m => m.CA.city);
}
else {
     q = q.OrderBy(m => m.CA.city); 
}
var results = q.ToList();
OrderBy和OrderByDescending是Linq-To-Entities兼容的方法,因此OrderBySQL生成可以正常工作。通知;但是,我明确地将它们使用的表达式设置为CA.city。 不幸的是,我不认为仅仅使用EF就可以动态地设置您想要的排序

如果你真的想这么做-看看LinqKit

它的“AsExpandable()”方法将允许您将表达式传递到方法中,然后可以编译并插入到linq查询中

所以你的新方法最终会被这样调用:

ReadTable("asc", m => m.CA.City, "120");
您必须为CA和BN创建一个显式包含类,然后使用如下表达式

public class Container {
    public tblCalifornia CA { get; set; }
    public tblBeach BN { get; set; }
}
public void ReadTable(string sortOrder, Expression<Func<Container,string>> fnSortExpr, string regID) {

    var sort = fnSortExpr.Compile();
    var q = (from CA in db.tblCalifornia.AsExpandable() 
           join BN in db.tblBeach on CA.BeachID equals BN.BeachhID into ps
           from BN in ps.DefaultIfEmpty()
           where CA.RegID == regID && CA.tblLife.duration != null
           select new Container { BN = BN, CA = CA }
        );
    if (order == "desc") {
       q = q.OrderByDescending(sort);
    }
    else {
       q = q.OrderBy(sort); 
    }
    var results = q.ToList();
    ...
}
公共类容器{
公共tblCalifornia CA{get;set;}
公共tblBeach BN{get;set;}
}
公共void可读表(字符串排序器、表达式fnSortExpr、字符串regID){
var sort=fnSortExpr.Compile();
var q=(来自db.tblCalifornia.AsExpandable()中的CA)
将BN加入db.tblBeach在CA.BeachID上等于BN.BeachhID加入ps
来自ps.DefaultIfEmpty()中的BN
其中CA.RegID==RegID&&CA.tblLife.duration!=null
选择新容器{BN=BN,CA=CA}
);
如果(顺序=“描述”){
q=q.OrderByDescending(排序);
}
否则{
q=q.OrderBy(排序);
}
var结果=q.ToList();
...
}
AsExpandable()围绕IQueryable创建一个包装器,允许运行时将表达式转换为LINQ to实体可以理解的内容。首先必须对表达式调用.Compile(),然后在新的可扩展IQueryable中使用它。我假设您的sortBy字段是来自浏览器的字符串,在这种情况下,您必须在调用此方法之前将支持的字符串映射到表达式

我还没有测试上面的代码,但希望它能让您走上正轨。你想做的事情绝非易事,所以对自己要有耐心

祝你好运