C# EF6 EntityCommand获取参数和性能

C# EF6 EntityCommand获取参数和性能,c#,performance,linq,entity-framework,entity-framework-6,C#,Performance,Linq,Entity Framework,Entity Framework 6,在EF6上下文中,我想通过动态字段/属性过滤多个实体。我是EF新手,我的透视图被T-SQL、存储过程和动态SQL查询破坏得很厉害 例如,在ERP环境中,用户可以通过代码进行过滤,系统应返回: 客户ID=代码的客户 供应商ID=代码的供应商 用户ID=代码的用户 客户ID/供应商ID=代码的订单 等等 但不仅可以是一个代码,还可以过滤多个概念:名称、城市、日期。。。并且可能不适用于所有实体 因此,由于每个实体都有不同的属性名称来引用“代码”概念,我认为最好的解决方案是使用EntityComma

在EF6上下文中,我想通过动态字段/属性过滤多个实体。我是EF新手,我的透视图被T-SQL、存储过程和动态SQL查询破坏得很厉害

例如,在ERP环境中,用户可以通过代码进行过滤,系统应返回:

  • 客户ID=代码的客户
  • 供应商ID=代码的供应商
  • 用户ID=代码的用户
  • 客户ID/供应商ID=代码的订单
  • 等等
但不仅可以是一个代码,还可以过滤多个概念:名称、城市、日期。。。并且可能不适用于所有实体

因此,由于每个实体都有不同的属性名称来引用“代码”概念,我认为最好的解决方案是使用EntityCommand而不是LinQ

代码应该是这样的:

// Create a query that takes two parameters.
string eSqlCustomerQuery =
    @"SELECT VALUE Contact FROM AdventureWorksEntities.Customer AS Customer";
string eSqlCustomerQuery =
    @"SELECT VALUE Contact FROM AdventureWorksEntities.Customer AS Customer";
// Create a list of parameters
var param = new SortedList<string, EntityParameter>();

// for each clauses add a pamater and build the query command dynamically.
if(!code)
{
    eSqlCustomerQuery += "WHERE Customer.CustomerID = @CODE";
    eSqlSupplierQuery += "WHERE Supplier.SupplierID = @CODE";
    //... more entities to 
    param["CODE"].ParameterName = "CODE";
    param["CODE"].Value = code;
}
// more parameters here...

using (EntityConnection conn =
    new EntityConnection("name=AdventureWorksEntities"))
{
    conn.Open();
    using (EntityCommand cmd = new EntityCommand(eSqlCustomerQuery, conn))
    {
        cmd.Parameters.Add(param["CODE"]);
        cmd.Parameters.Add(param["DATE"]);
        // more parameters here...
    }
    // the same for each query...
    // ...
    // run all the queries ...
    // ...
    // Etc.
    conn.Close();
}
//创建一个包含两个参数的查询。
字符串eSqlCustomerQuery=
@“选择AdventureWorksEntities中的价值联系人。客户作为客户”;
字符串eSqlCustomerQuery=
@“选择AdventureWorksEntities中的价值联系人。客户作为客户”;
//创建参数列表
var param=new SortedList();
//对于每个子句,添加一个pamater并动态生成query命令。
如果(!代码)
{
eSqlCustomerQuery+=“WHERE Customer.CustomerID=@CODE”;
eSqlSupplierQuery+=“WHERE Supplier.SupplierID=@CODE”;
//…更多实体
param[“CODE”]。ParameterName=“CODE”;
参数[“代码”]。值=代码;
}
//这里有更多参数。。。
使用(实体连接接头)=
新EntityConnection(“名称=AdventureWorksEntities”))
{
conn.Open();
使用(EntityCommand cmd=new EntityCommand(eSqlCustomerQuery,conn))
{
cmd.Parameters.Add(param[“CODE”]);
cmd.Parameters.Add(参数[“日期]);
//这里有更多参数。。。
}
//每个查询都相同。。。
// ...
//运行所有查询。。。
// ...
//等等。
康涅狄格州关闭();
}
我的问题有三个:

  • 在我执行
    cmd=new EntityCommand(eSqlCustomerQuery,conn)
    时,我可以使用类似于
    System.Data.SqlClient.SqlCommandBuilder.DeriveParameters(cmd)的东西吗
  • 由于此动态查询非常动态,因此可以缓存或具有可重用的执行计划,如何改进它?
  • 是否可以以更干净的方式使用LinQ执行此操作?
    • 像这样使用LINQ:

      //define base LINQ
      Contracts = from R in AdventureWorks.Customer select R; //there is IQueryable, not actually     materialized
      
      //tune filters, no records will fetched
      Result = Contracts;
      if (code!=null) Result = Result.Where(_=>_.Code==code);
      if (date!=null) Result = Result.Where(_=>_.Date==date);
      
      //materialize records
      Records = Result..Select(_=>_.Contract).ToArray();
      

      您可以创建动态linq查询。这些应该被缓存。在我的博客文章中可以看到一个这样做的例子:您可以使用动态构建查询。一个很大的优势是您没有所有这些无法维护的字符串文本。