EF6 EntityCommand获取参数和性能

时间:2013-10-23 18:12:16

标签: c# performance linq entity-framework entity-framework-6

在EF6环境中,我想通过动态字段/属性过滤多个实体。我是EF的新手,我的观点被T-SQL和存储过程以及动态SQL查询破坏了。

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

  • CustomerID = code
  • 的客户
  • SupplierID = code
  • 的供应商
  • UserID = code
  • 的用户
  • 订单为CustomerID / SupplierID =代码

但不仅仅是一个代码,可以将概念倍增来过滤:名称,城市,日期......并且可能都不适用于所有实体。

因此,由于每个实体都有不同的属性名称来引用“代码”概念,我认为最好的解决方案是使用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();
}

我的问题是3:

  • 当我正在cmd = new EntityCommand(eSqlCustomerQuery, conn)时,我可以使用类似System.Data.SqlClient.SqlCommandBuilder.DeriveParameters(cmd);的内容吗?
  • 由于此动态查询非常动态,可以缓存或具有可重复使用的执行计划,如何改进?
  • 是否可以更清洁地使用LinQ?

1 个答案:

答案 0 :(得分:0)

像这样使用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();