简体   繁体   English

使用LINQ使用PredicateBuilder对实体进行动态查询

[英]Dynamic query with linq to entities using PredicateBuilder

I'm trying to run a query on a very simple table but I'm not getting to any result. 我正在尝试在一个非常简单的表上运行查询,但是没有任何结果。 The table contains an action log with the following columns: 该表包含带有以下列的操作日志:

  • ID ID
  • ActionTypeID (create, edit or delete) ActionTypeID(创建,编辑或删除)
  • EntryID (the id of the created/edited/or deleted entry) EntryID(已创建/已编辑/已删除条目的ID)
  • TableName (where the action was committed) TableName(在其中提交操作的位置)
  • ControlName 控件名称
  • Person (who committed the action. nt-user with department) 人员(已执行操作。部门的nt用户)
  • Date 日期

What I wanted to get is a list of all EntryIDs with ActionTypeID == 1 and Person (department) ending with one of a dynamic list of strings. 我想要得到的是ActionTypeID == 1的所有EntryID的列表,并且Person(部门)以动态字符串列表之一结尾。 The Problem is that only the first action for one EntryID in the action log should be checked to match one of these departments. 问题在于,仅应检查操作日志中一个EntryID的第一个操作,以匹配这些部门中的一个。

I know this sounds pretty weird. 我知道这听起来很奇怪。 This may result from my bad english and from the database designing disability of my former colleague. 这可能是由于我的英语不好以及我的前同事的数据库设计功能不佳造成的。 I don't know which is worse. 我不知道哪个更糟。

My attempt to get the result I wanted is this: 我尝试获得想要的结果是这样的:

var predicate = PredicateBuilder.False<ActionLog>();
var pOuter = PredicateBuilder.True<ActionLog>();

pOuter = pOuter.And(h => h.TableName.ToUpper() == "Contact".ToUpper());
pOuter = pOuter.And(h => h.ActionType.ID == 1);

foreach (var dep in b.DepartmentList)
{
    predicate = predicate.Or(x => x.Person.EndsWith("/" + dep.Value));
}

pOuter = pOuter.And(predicate.Expand());

mContactIDs = (from h in db.ActionLog
orderby h.Date
select h).AsExpandable().Where(pOuter).Select(x => x.EntryID).Distinct().ToList();

But this returns me all entries where the 'Person' ends with the selected departments. 但这会返回所有条目,其中“人员”以所选部门结尾。 I just want to check the first entry with this EntryID. 我只想使用此EntryID检查第一个条目。

I hope anyone understands what I'm trying to translate from confused german to weird english. 我希望任何人都能理解我要从困惑的德语到奇怪的英语的翻译。

oh- by the way, it's .Net 3.5 哦,对了,它是.Net 3.5

EDIT I think I have some problems finding the right explanation - I'll try it with some dummy data. 编辑我认为我在找到正确的解释时遇到一些问题-我将使用一些虚拟数据进行尝试。

ID | ActionTypeID | EntryID | TableName  | ControlName | Person             | Date
----------------------------------------------------------------------------------------
1  | 1            | 3       | 'Contacts' | NULL        | 'xxxx/department1' | 04/11/2012
2  | 1            | 3       | 'Contacts' | NULL        | 'yyyy/department2' | 04/11/2012
3  | 1            | 5       | 'Contacts' | NULL        | 'yyyy/department2' | 04/13/2012
4  | 1            | 14      | 'Contacts' | NULL        | 'zzzz/department1' | 04/16/2012

In my example i would be searching for log entries with "Person ends with '/department2' created the first occurrence of a new EntryID", "TableName == 'Contacts'" and "ActionTypeID == 1". 在我的示例中,我将搜索以下日志条目:“人员以'/ department2'结尾,并首次出现新的EntryID”,“ TableName =='Contacts'”和“ ActionTypeID == 1”。 The result I want to receive would be (only EntryIDs) 5, as this is the only entry where a user of department2 has been the first one Inserting this EntryID with ActionTypeID 1. I know this is stupid and if I had designed the database I wouldn't have done it this way, but now I have to deal with it. 我要接收的结果是(仅EntryIDs)5,因为这是Department2的用户是第一个插入该条目的唯一条目,该条目以ActionTypeID 1插入。我知道这很愚蠢,如果我设计了数据库,不会这样做,但是现在我必须处理它。 If the quantity of departments to query would not be dynamic I would use this snippet: 如果要查询的部门数量不是动态的,我将使用以下代码段:

IQueryable<ActionLog> log = db.ActionLog;
mContactIDs = (from k in db.Contacts
    where (from h in log
        where h.TableName == "Contacts"
        && h.EntryID == k.ID
        && h.ActionType.ID == 1
        orderby h.Date
        select h).FirstOrDefault().Person.EndsWith("/" + b.Department)
    select k.ID).ToList();

But I don't know how to connect those dynamic departments with the stupid design (and multiple ActionTypeID 1 (create) for one entry. I don't even know why the application saves this) 但是我不知道如何将这些动态部门与愚蠢的设计(以及为一个条目创建多个ActionTypeID 1(创建))连接。我什至不知道为什么应用程序会保存这个)

Thank you, Ben. 谢谢你,本

I think the problem is the captured variable value(ie dep.Value ) inside foreach loop. 我认为问题是在foreach循环内捕获的变量值(即dep.Value )。 Make a copy of the variable and use that in the expression. 复制变量并在表达式中使用它。 The issue is explained here . 这个问题在这里解释。

foreach (var dep in b.DepartmentList)
{
    var depValue = dep.Value;
    predicate = predicate.Or(x => x.Person.EndsWith("/" + depValue));
}

I decided to use Entity SQL instead. 我决定改用Entity SQL。

        List<int> mContactIDs = new List<int>();
        using (var db = new Entities())
        {
            string queryString = @"
                                SELECT  
                                    VALUE H.EntryID
                                FROM    
                                    Entities.ActionLog AS H
                                WHERE 
                                    H.ID IN (
                                        SELECT VALUE TOP (1) Hi.ID
                                        FROM Entities.ActionLog AS Hi
                                        WHERE Hi.ActionType.ID = 1
                                        AND Hi.TableName = 'Kontakt'
                                        AND Hi.EntryID = H.EntryID
                                        ORDER BY Hi.Date    
                                    )
                                {0}
                                GROUP BY H.EntryID";

            List<string> lDepartments = new List<string>();
            foreach (var dep in b.DepartmentList)
            {
                lDepartments.Add(string.Format(" H.Person LIKE '%{0}' ", dep.Value));
            }

            string sDepartmentQuery = string.Empty;
            if (lDepartments.Count > 0)
            {
                sDepartmentQuery = string.Format(" AND ({0}) ", string.Join(" OR ", lDepartments.ToArray()));
            }

            var result = db.CreateQuery<int>(string.Format(queryString, sDepartmentQuery));
            if (result != null && result.Count() > 0)
            {
                mContactIDs = result.ToList();
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在MVC 4的局部视图中访问动态linq查询的结果(PredicateBuilder linq到实体)? - How to access results of dynamic linq query (PredicateBuilder linq to entities) in a partial view in MVC 4? 没有PredicateBuilder的LINQ中的动态OR - Dynamic OR in LINQ without the PredicateBuilder Linq查询语法与PredicateBuilder? - Linq query syntax with PredicateBuilder? C# 动态 Linq 使用 Fluent Mongo 查询 - 不使用 Contains 或 PredicateBuilder - C# Dynamic Linq Query with Fluent Mongo - Without using Contains or PredicateBuilder C# PredicateBuilder Entities:在指定的 LINQ to Entities 查询表达式中未绑定参数“f” - C# PredicateBuilder Entities: The parameter 'f' was not bound in the specified LINQ to Entities query expression 嵌套PredicateBuilder谓词:“参数&#39;f&#39;在指定的LINQ to Entities查询表达式中未绑定” - Nesting PredicateBuilder predicates : 'The parameter 'f' was not bound in the specified LINQ to Entities query expression' 在Dynamic LINQ to Entities中使用DateTime - Using DateTime in Dynamic LINQ to Entities 使用LINQ进行实体动态联接 - Using LINQ to Entities dynamic JOIN 在EF Linq to Entities中使用动态linq - Using dynamic linq in EF Linq to Entities 如何为实体查询创建动态linq - How to create a dynamic linq to entities query
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM