C# 在多对象上下文中重用查询

C# 在多对象上下文中重用查询,c#,asp.net,entity-framework,linq-to-entities,C#,Asp.net,Entity Framework,Linq To Entities,本周末,我正在使用任务并行化一段代码,以运行仪表板页面所需的所有查询 我现在有很多复制/粘贴方法,它们几乎完全相同的查询,并且在方法的最后有一行不同的内容 有没有一种方法可以针对一个对象上下文编写查询,然后将其分离并传递给一个方法 我想这样做: using(DbContext db = new DbContext) { var query = db.cars.where(x => x.make == "Ford"); int handleCounts = getDoorHan

本周末,我正在使用任务并行化一段代码,以运行仪表板页面所需的所有查询

我现在有很多复制/粘贴方法,它们几乎完全相同的查询,并且在方法的最后有一行不同的内容

有没有一种方法可以针对一个对象上下文编写查询,然后将其分离并传递给一个方法

我想这样做:

using(DbContext db = new DbContext)
{
   var query = db.cars.where(x => x.make == "Ford");

   int handleCounts = getDoorHandleCounts(query);
}

public int getDoorHandleCounts(type? query)
{
     using(DbContext db = new DbContext())
     {
          return query.where(x => x.partType == "DoorHandle").Count();
     }
 }
{
   ...
   int handleCounts = getDoorHandleCounts("Ford");
}

public int getDoorHandleCounts(string Make)
{
     using(DbContext db = new DbContext())
     {
          return db.cars.where(x => x.make == Make && x.partType == "DoorHandle").Count();
     }
 }
有什么想法吗

请记住,所有my count()方法都是从任务数组启动的,因此它们将并行运行。我需要一个新的对象上下文来运行每个计数查询


我在谷歌上搜索了一下,并考虑尝试使用一个预编译的查询并从不同的对象上下文调用它,但我真正的查询有点复杂,需要分配if块来确定where条件。你能编译一个不是很简单的查询吗?

也许我误解了这个问题,但这不符合你的要求吗

using(DbContext db = new DbContext)
{
   var carsResult = db.cars.where(x => x.make == "Ford");

   int handleCounts = getDoorHandleCounts(carsResult);
}

public int getDoorHandleCounts(IEnumerable<Car> result)
{
     return result.where(x => x.partType == "DoorHandle").Count();         
}
使用(DbContext db=new DbContext)
{
var carsResult=db.cars.where(x=>x.make==“福特”);
int handleCounts=getDoorHandleCounts(carsResult);
}
公共int getDoorHandleCounts(IEnumerable结果)
{
返回结果。其中(x=>x.partType==“DoorHandle”).Count();
}
编辑:没关系,我现在才看到你提到的任务数组。

更改

public int getDoorHandleCounts(type? query)


无法从上下文分离查询并将其附加到上下文。但是,可以重用第一个表达式:

Expression<Func<Car,bool>> InitialSelection()
{
    return x => x.make == "Ford";
}

public int GetDoorHandleCounts()
{
    using(DbContext db = new DbContext())
    {
        return db.Cars()
               .Where(InitialSelection())
               .Where(x => x.partType == "DoorHandle").Count();
    }
}
这仅在初始查询为“简单”时有效,即不包含连接集上的连接和谓词,您应该在每个
getX
方法中反复重复这些连接集和谓词

或者,您可以初始化上下文并将其提供给返回查询的方法:

public IQueryable<Car> GetInitialQuery(DbContext db)
{
    return db.Cars().Join(....)
           .Where(x => x.make == "Ford")
           .Where(....);
}

public int GetDoorHandleCounts()
{
    using(DbContext db = new DbContext())
    {
        return GetInitialQuery(db)
               .Where(x => x.partType == "DoorHandle").Count();
    }
}
公共IQueryable GetInitialQuery(DbContext db) { 返回db.Cars().Join(..) .其中(x=>x.make==“福特”) .其中(……); } public int GetDoorHandleCounts() { 使用(DbContext db=new DbContext()) { 返回GetInitialQuery(db) 其中(x=>x.partType==“门把手”).Count(); } }
很有趣,所以如果我将查询作为IQueryable传递,我可以在不同的对象上下文中运行它,然后我用创建它?不,只是意识到这正是您要做的。为什么你可以通过原始过滤器,每次通过都重新创建查询?这听起来像是我想做的,你有没有我可以查看的参考资料或示例?我只是说通过过滤器的字符串值,然后创建一个新的查询。请看我的编辑。谢谢你的建议。这与我现在所做的类似,但where子句有点大,如果将其拆分为许多不同的方法,将不利于维护/可读性。如果可能的话,我想找出一种传递基本查询的方法,并在最后添加最后一个where和count调用。
int handleCounts = getDoorHandleCounts();
public IQueryable<Car> GetInitialQuery(DbContext db)
{
    return db.Cars().Join(....)
           .Where(x => x.make == "Ford")
           .Where(....);
}

public int GetDoorHandleCounts()
{
    using(DbContext db = new DbContext())
    {
        return GetInitialQuery(db)
               .Where(x => x.partType == "DoorHandle").Count();
    }
}