2013-10-23 15 views
0

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

例如在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(); 
    } 
    

    我的问题是3:

    • 当时我正在做我cmd = new EntityCommand(eSqlCustomerQuery, conn)可以使用类似System.Data.SqlClient.SqlCommandBuilder.DeriveParameters(cmd);
    • 由于这个动态查询是如此动态以至于它可以被缓存或者有一个可重用的执行计划,它如何被改进?
    • 是否有可能用更清洁的方式与LinQ做到这一点?
  • +0

    您可以创建动态的LINQ查询。这些应该被缓存。在我的博客文章中查看这样做的示例:http://blog.3d-logic.com/2013/03/24/hacking-linq-to-entities-with-expressions-part-1-really-generic-repository/ – Pawel

    +0

    您可以使用[PredicateBuilder](http://www.albahari.com/nutshell/predicatebuilder.aspx)动态构建查询。一个很大的优点是你没有得到所有这些不可维护的字符串文字。 –

    回答

    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();