Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.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

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
C# 我可以在林肯克隆一个IQueryable吗?为了工会的目的?_C#_Linq_Entity Framework - Fatal编程技术网

C# 我可以在林肯克隆一个IQueryable吗?为了工会的目的?

C# 我可以在林肯克隆一个IQueryable吗?为了工会的目的?,c#,linq,entity-framework,C#,Linq,Entity Framework,我有一张工作订单表。该表有一个PrimaryWorker和PrimaryPay字段。它还有一个SecondaryWorker和SecondaryPay字段(可以是null) 我希望运行两个非常类似的查询并合并它们,这样它将返回一个Worker字段和Pay字段。因此,如果一个WorkOrder记录同时填充了PrimaryWorker和SecondaryWorker字段,我将得到2条记录 这两个查询的“where子句”部分非常相似,而且很长。这里有一个虚拟的例子 var q = ctx.WorkOr

我有一张
工作订单表
。该表有一个
PrimaryWorker
PrimaryPay
字段。它还有一个
SecondaryWorker
SecondaryPay
字段(可以是
null

我希望运行两个非常类似的查询并合并它们,这样它将返回一个
Worker
字段和
Pay
字段。因此,如果一个
WorkOrder
记录同时填充了
PrimaryWorker
SecondaryWorker
字段,我将得到2条记录

这两个查询的“where子句”部分非常相似,而且很长。这里有一个虚拟的例子

var q = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);

if(showApprovedOnly)
{
   q = q.Where(w => w.IsApproved);
}
//...more filters applied
var q=ctx.WorkOrder.Where(w=>w.WorkDate>=StartDt&w.WorkDate w.IsApproved);
}
//…应用了更多过滤器
现在我还有一个名为
hideZeroPay
的搜索标志。如果这是真的,我不想包括记录,如果工人被支付$0。但显然,对于一个查询,我需要比较
PrimaryPay
字段,而在另一个查询中,我需要比较
SecondaryPay
字段

所以我想知道怎么做


我是否可以克隆我的基本查询
q
,并从中生成一个主要和次要辅助查询,然后将这两个查询合并在一起?

当您执行第二个操作时,您实际上是在克隆查询

您可以在这里创建初始的可查询对象

var q = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);
您只需创建一个新变量来存储查询

var qw = q.Where(w=> w.IsApproved);

这是因为queryable是作为一个对象创建的,查询本身只有在您枚举它之后才会运行。

嗯,我不确定是否理解您的意图。但我认为克隆不是必要的。为什么不从基本查询中拆分两个新查询


var baseQuery = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);

IQueryable<WorkOrder> query1;
if (showApprovedOnly)
{
  query1 = baseQuery.Where(w => w.IsApproved);
}
//more filters on query1
...

IQueryable<WorkOrder> query2;
if (/*something*/)
  query2 = baseQuery.Where(w => w.SomeThing);

var baseQuery=ctx.WorkOrder.Where(w=>w.WorkDate>=StartDt&&w.WorkDate w.IsApproved);
}
//查询1上的更多筛选器
...
易读查询2;
如果(/*某物*/)
query2=baseQuery.Where(w=>w.SomeThing);
定义查询后,您可以解释它们(每个枚举)并检索不同的结果


var res1=query1.ToList();
var res2=query2.ToList();

哦!出于某种原因,我一直认为我总是添加到同一个查询对象中,但您的意思是,实际上,每次调用像where()这样的linq函数时,都会返回一个新的不同的查询对象。。比如String.Substring()如何重新生成一个新字符串&不是修改过的同一个字符串?如果是这样的话,那就太好了。返回query1和query2的并集的最佳方式是什么?理想情况下,我希望它都能在数据库上运行。经过思考,我不得不说你的想法也出现了。原因是ObjectQuery对象。嗯,当我写我的答案时,我只是在猜测,但现在我知道它是有效的。我不知道是否在数据库上执行了.Union()。但我对你的结果感兴趣,在你试过之后;o) 是的,似乎每次都会返回一个新的ObjectQuery,因为query1.equals(query2)返回false。我注意到在调用Union()之前,我必须对每个查询执行投影(Select()),以使其正常工作。然后,我在ObjectQuery上运行了一个ToTraceString(),它完成了在DB上运行的所有操作。。。对于另一个DbContext实例。目前,如果您为一个DbContext实例构建了一个复杂的查询,则无法将其重新用于另一个DbContext。您可以创建一个帮助器来构建它,但仍然需要重新构建它。这似乎有很多不必要的开销。例如,如果您只想在同一IQueryable上并行运行CountAsync和Skip/Take/ToListSync,则不能这样做,因为要安全地并行运行它们,需要两个单独的DbContext实例。

var baseQuery = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);

IQueryable<WorkOrder> query1;
if (showApprovedOnly)
{
  query1 = baseQuery.Where(w => w.IsApproved);
}
//more filters on query1
...

IQueryable<WorkOrder> query2;
if (/*something*/)
  query2 = baseQuery.Where(w => w.SomeThing);

var res1 = query1.ToList();
var res2 = query2.ToList();