【问题标题】:Dynamic Search Using Entity Framework使用实体框架进行动态搜索
【发布时间】:2018-11-21 14:20:19
【问题描述】:

我有一个使用 Entity Framework 的带有可选字段的搜索屏幕,我想构建一个动态查询而不选择对象并对其进行过滤。

我想优化以下现有搜索,我不想选择“var query = from p in context.APLCN_TRCKR select p;”在这个阶段,因为该应用程序将同时被 100 多人使用:

using (var context = new VASTEntities())
{
    var query = from p in context.APLCN_TRCKR select p;

    if (!string.IsNullOrEmpty(searchObj.CUST_NAME_X))
        query = query.Where(p => p.CUST_NAME_X == searchObj.CUST_NAME_X.Trim());

    if (!string.IsNullOrEmpty(searchObj.SURNM_X))
        query = query.Where(p => p.CUST_SURNM_X == searchObj.SURNM_X.Trim());

    if (!string.IsNullOrEmpty(searchObj.QUEUE_ID))
        query = query.Where(p => p.QUEUE_ID == searchObj.QUEUE_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.BP_ID))
        query = query.Where(p => p.BPID == searchObj.BP_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.UserID))
        query = query.Where(p => p.CURR_OWNR_USER_ID == searchObj.UserID.Trim());

    if (!string.IsNullOrEmpty(searchObj.APLCN_TRCKR_ID))
        query = query.Where(p => p.APLCN_TRCKR_ID == searchObj.APLCN_TRCKR_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.APLCN_STTS_ID))
        query = query.Where(p => p.APLCN_STTS_ID == searchObj.APLCN_STTS_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.CUST_ID))
        query = query.Where(p => p.CUST_ID == searchObj.CUST_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.CELL_ID))
        query = query.Where(p => p.CELL_ID == searchObj.CELL_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.ORIGN_ID))
        query = query.Where(p => p.ORIGN_ID == searchObj.ORIGN_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.ORGTN_CHANL_ID))
        query = query.Where(p => p.ORGTN_CHANL_ID == searchObj.ORGTN_CHANL_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.CR_DCSN_ID))
        query = query.Where(p => p.CR_DCSN_ID == searchObj.CR_DCSN_ID.Trim());

    if (!string.IsNullOrEmpty(searchObj.SBSA_CUST_I))
        query = query.Where(p => p.SBSA_CUST_I == searchObj.SBSA_CUST_I.Trim());

    if (!string.IsNullOrEmpty(searchObj.USER_ID_APP_CRTD))
        query = query.Where(p => p.USER_ID_APP_CRTD == searchObj.USER_ID_APP_CRTD.Trim());

    if (!string.IsNullOrEmpty(searchObj.RGION_ID))
    {
        int r = int.Parse(searchObj.RGION_ID.Trim());
        query = query.Where(p => p.RGION_ID == r);
    }

    if (!string.IsNullOrEmpty(searchObj.CR_REGION))
    {
        int x = int.Parse(searchObj.CR_REGION);

        if (x == 0)
        {
            // check 0 - not applicable or null
            query = query.Where(p => p.CR_REGION_ID == 0 || p.CR_REGION_ID == null);
        }
        else
        {
            query = query.Where(p => p.CR_REGION_ID == x);
        }
    }

    if (!string.IsNullOrEmpty(searchObj.Process_Type))
        query = query.Where(p => p.PRCES_TYPE_ID == searchObj.Process_Type.Trim());

    query.ToList();

    foreach (var a in query)
    {
         searchAppsObj.Add(Translator.TranslateReqObjToBO.TranslateDTOToSearchApp(a));
    }

    if (query.Count() == 0)
    {
        throw new Exception("No Applications Found.");
    }

    context.Connection.Close();
    return searchAppsObj;
}

我想做这样的事情,但是这个工作不正常:

string cust_name_x = "", surname_x = "", queue_id = "", bp_id = "", user_id = "", aplcn_trckr_id = "",
               aplcn_stts_id = "", cust_id = "", process_type = "", cr_region = "", cell_id = "", Origin = "", region = "", channel = "", credit_verdict = "", sbsa_cust_id = "", app_creator_id = "";

            if (!string.IsNullOrEmpty(searchObj.CUST_NAME_X))
                cust_name_x = searchObj.CUST_NAME_X.Trim();
            if (!string.IsNullOrEmpty(searchObj.SURNM_X))
                surname_x = searchObj.SURNM_X.Trim();
            if (!string.IsNullOrEmpty(searchObj.QUEUE_ID))
                queue_id = searchObj.QUEUE_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.BP_ID))
                bp_id = searchObj.BP_ID;
            if (!string.IsNullOrEmpty(searchObj.UserID))
                user_id = searchObj.UserID.Trim();
            if (!string.IsNullOrEmpty(searchObj.APLCN_TRCKR_ID))
                aplcn_trckr_id = searchObj.APLCN_TRCKR_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.APLCN_STTS_ID))
                aplcn_stts_id = searchObj.APLCN_STTS_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.CUST_ID))
                cust_id = searchObj.CUST_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.Process_Type))
                process_type = searchObj.Process_Type.Trim();
            if (!string.IsNullOrEmpty(searchObj.CR_REGION))
                cr_region = searchObj.CR_REGION.Trim();
            if (!string.IsNullOrEmpty(searchObj.CELL_ID))
                cell_id = searchObj.CELL_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.ORIGN_ID))
                Origin = searchObj.ORIGN_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.RGION_ID))
                region = searchObj.RGION_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.ORGTN_CHANL_ID))
                channel = searchObj.ORGTN_CHANL_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.CR_DCSN_ID))
                credit_verdict = searchObj.CR_DCSN_ID.Trim();
            if (!string.IsNullOrEmpty(searchObj.SBSA_CUST_I))
                sbsa_cust_id = searchObj.SBSA_CUST_I.Trim();
            if (!string.IsNullOrEmpty(searchObj.USER_ID_APP_CRTD))
                app_creator_id = searchObj.USER_ID_APP_CRTD.Trim();




            using (var context = new VASTEntities())
            {
                var query = from p in context.APLCN_TRCKR

                            where
                            p.CUST_NAME_X.Contains(cust_name_x) &&
                            p.CUST_SURNM_X.Contains(surname_x) &&
                            p.QUEUE_ID.Contains(queue_id) &&
                            p.BPID.Contains(bp_id) &&
                            p.CURR_OWNR_USER_ID.Contains(user_id) &&
                            p.APLCN_TRCKR_ID.Contains(aplcn_trckr_id) &&
                            p.APLCN_STTS_ID.Contains(aplcn_stts_id) &&
                            p.CUST_ID.Contains(cust_id) &&
                            p.PRCES_TYPE_ID.Contains(process_type) &&
                            p.CELL_ID.Contains(cell_id) &&
                            SqlFunctions.StringConvert((double)p.CR_REGION_ID).Contains(cr_region) &&
                            p.ORIGN_ID.Contains(Origin) &&
                            SqlFunctions.StringConvert((double)p.RGION_ID).Contains(region) &&
                            p.ORGTN_CHANL_ID.Contains(channel) &&
                            p.CR_DCSN_ID.Contains(credit_verdict) &&
                            p.SBSA_CUST_I.Contains(sbsa_cust_id) 

                            select p;

                query.ToList();
                if (query.Count() == 0)
                {
                    throw new Exception("No Applications Found.");
                }
                foreach (var a in query)
                {
                    searchAppsObj.Add(Translator.TranslateReqObjToBO.TranslateDTOToSearchApp(a));
                }
                context.Connection.Close();
                return searchAppsObj;

            }

【问题讨论】:

    标签: asp.net entity-framework wcf linq-to-sql linq-to-entities


    【解决方案1】:

    你可以像下面这样创建一个 lambda 表达式的集合:

    var filters = new List<Expression<Func<Application, bool>>();
    
    if (!string.IsNullOrWhitespace(searchObj.CUST_NAME_X))
        filters.Add(application => application .CUST_NAME_X.Contains(searchObj.CUST_NAME_X.Trim());
    
    if (!string.IsNullOrEmpty(searchObj.SURNM_X))
        filters.Add(application => application .CUST_SURNM_X.Contains(searchObj.SURNM_X.Trim());
    
    // And so on for all criteria
    

    之后,您可以在filters 上执行循环,如下所示:

    using (var context = new VASTEntities())
    {
        var query = context.APLCN_TRCKR;
        foreach(var filter in filters)
        {
            query = query.Where(filter);
        }
    
        var result = query.ToList();
        if (result.Count() == 0)
        {
            throw new Exception("No Applications Found.");
        }
        foreach (var a in result)
        {
            searchAppsObj.Add(Translator.TranslateReqObjToBO.TranslateDTOToSearchApp(a));
        }
        context.Connection.Close();
        return searchAppsObj;
    }
    

    【讨论】:

    • 您好,谢谢您的回复,这里的应用程序是什么:filters.Add(application => application .CUST_SURNM_X.Contains(searchObj.SURNM_X.Trim());
    • @sibonisozungu application 只是您的 dbset context.APLCN_TRCKR 中的一个类型的参数。如果您想要它只是一个参数名称,您可以重命名它。如果var filters = new List&lt;Expression&lt;Func&lt;Application, bool&gt;&gt;(); 您需要将Application 替换为context.APLCN_TRCKR 中使用的正确类型,那么这里唯一需要注意的是。
    • 谢谢,我已将 Application 替换为表名,现在出现此错误:严重性代码描述项目文件行抑制状态错误 CS0266 无法隐式转换类型 'System.Linq.IQueryable' 到'System.Data.Objects.ObjectSet'。存在显式转换(您是否缺少演员表?)
    • 成功了 谢谢@CodeNotFound 我不得不更改查询类型:IQueryable query = context.APLCN_TRCKR;
    【解决方案2】:

    改变

    var query = from p in context.APLCN_TRCKR select p;
    

    var query = context.APLCN_TRCKR.AsQueryable();
    

    而当过滤工作完成时:

    await query.ToListAsync() // this one goes to the database
    

    也看看这个:Linq query filtering

    另外:不要调用context.Connection.Close();,因为这无论如何都会被执行,因为using 的行为类似于try { ... } finally { // dispose work }

    【讨论】:

      猜你喜欢
      • 2015-07-25
      • 1970-01-01
      • 2021-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多