0

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

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

  • 客户 ID = 代码
  • 供应商 ID = 代码的供应商
  • 用户 ID = 代码的用户
  • 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 进行操作?
4

1 回答 1

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();
于 2014-10-05T08:15:53.187 回答