动态LINQ集合?

时间:2009-08-20 13:05:23

标签: c# asp.net entity-framework dynamic-linq

我有一个项目要求我做这么大的搜索引擎,但这一切都是动态的。我的意思是我可以拥有大约0到9个主要的“组”,这些组内部的东西就像是“无论是”“或”与“或”的无限可能性。我们首先想到的是使用Dynamic Linq,它提供了构建动态查询的良好替代方案。所有这些都使用EF和自制包装。

问题: 我无法访问“收藏”。我的意思是,我可以轻松访问引用的对象(如 Customer.State.StateName =“New-York”或Custoemr.State.StateName =“Quebec”)但我找不到方法访问类似:“Customer.Orders.OrderID = 2 OR Customer.Orders.OrderID = 3”。我可以很容易地弄清楚这是因为它是一个集合,但我怎么能这样做呢?

请帮帮我!!

**抱歉我的英文!!


更新

我不清楚我是否愿意,对不起因为我是法国人......

我的问题是因为没有什么是静态的。它是一个候选人搜索引擎,用于将候选人放入企业的重新制定的公司。在经理可以搜索候选人的页面中,他可以通过以下方式“解析”:域名(工作),城市或其他许多用户在注册时填写的内容。所有这些格式(如果它在SQL中):

[...] WHERE(domaine.domainID = 3 OR domaine.domainID = 5 OR domaine.domainID = 23)AND(cities.cityID = 4,cities.city = 32)[...]

所以我不能用普通的LINQ格式来做到这一点,如:

Candidat.Domaines.Where(domain => domain.DomainID == 3 || domain.DomainID == 5 || domain.DomainID == 23);

即使是paretheses中的操作员也是动态的(“AND”或“OR”)!这就是我们尝试使用Dynamic Linq的原因,因为它更灵活。

希望它更容易理解我的问题...


更新2 这是我的方法

private string BuildDomainsWhereClause() {
        StringBuilder theWhere = new StringBuilder();

        if (this.Domaines.NumberOfIDs > 0) {
            theWhere.Append("( ");

            theWhere.Append(string.Format("Domaines.Where( "));
            foreach (int i in this.Domaines.ListOfIDs) {
                if (this.Domaines.ListOfIDs.IndexOf(i) > 0) {
                    theWhere.Append(string.Format(" {0} ", this.DispoJours.AndOr == AndOrEnum.And ? "&&" : "||"));
                }
                theWhere.Append(string.Format("DomaineId == {0}", i));
            }
            theWhere.Append(" ))");
        }

        return theWhere.ToString();
    }

它的效果很好,而不是“不返回布尔值”。那我该怎么办? 错误:“预期类型'布尔'的表达式。

最后,它会返回类似:“(Domaines.Where(DomaineId == 2&&DomaineId == 3&& DomaineId == 4&& DomaineId == 5))。”这被添加到我的LINQ查询中:

var queryWithWhere = from c in m_context.Candidats.Where(WHERE)
                                     select c;

不要忘记,还有7或8个“可能”添加的内容可供搜索...任何想法?

5 个答案:

答案 0 :(得分:5)

您需要做的是构建 LambdaExpression (更具体地说是Expression<Func<T, bool>>)。你不能使用字符串。您可以构建一个这样的简单表达式:

ParameterExpression p = Expression.Parameter(typeof(Domaine), "domaine");
Expression<Func<Domaine, bool>> wherePredicate = 
  Expression.Lambda<Func<Domaine, bool>>(
    Expression.Or(
      Expression.Equal(
        Expression.Property(p, "DomainID"),
        Expression.Constant(10)),
      Expression.Equal(
        Expression.Property(p, "DomainID"),
        Expression.Constant(11))
      ), p);

即,

  

domaine.DomainID = 10 || domaine.DomainID = 11

如果您需要手动执行此操作,则不太可读。

有一个完全可操作的表达式解析器示例,它实际上会根据MSDN代码库中C# Samples for Visual Studio 2008 DynamicQuery 下的字符串为您执行此操作。 (LinqDataSource控件在内部使用此示例的略微修改版本。)

答案 1 :(得分:4)

最终我完全按照我想要的方式得到了它。

private string BuildDomainsWhereClause() {
        StringBuilder theWhere = new StringBuilder();

        if (this.Domains.NumberOfIDs > 0) {
            theWhere.Append("( ");

            foreach (int i in this.Domains.ListOfIDs) {
                if (this.Domains.ListOfIDs.IndexOf(i) > 0) {
                    theWhere.Append(string.Format(" {0} ", this.Domains.AndOr == AndOrEnum.And ? "&&" : "||"));
                }
                theWhere.Append(string.Format("Domains.Any(IdDomaine== {0})", i));
            }
            theWhere.Append(" )");
        }

        return theWhere.ToString();
    }

产生类似的东西:“(DispoJours.Any(IdDispo == 3)&amp;&amp; DispoJours.Any(IdDispo == 5))”。

我所有其他的“Where builder”将使用“&amp;&amp;”来做同样的事情。给出正确的结果。

后来:

var queryWithWhere = from c in m_context.Candidats.Where(WHERE)
                     select c;

WHOOOHOOO !!谢谢大家。非常有用!喜欢这个网站!


<强>更新

不要忘记我在此查询中使用Dynamic Linq。这不是一个普通的LINQ查询。

答案 2 :(得分:1)

假设Customer.Orders返回一个集合,这正是您不能只调用它的属性的原因。

为了使用LINQ来获取您正在寻找的订单,您需要知道OrderID(或其他一些属性),在这种情况下您可以这样做:

Customer.Orders.Find(order => order.OrderID == 2);

编辑:要以这种方式添加表达式以查找ID 2或3:

Customer.Orders.FindAll(order => order.OrderID == 2 || order.OrderID == 3);

答案 3 :(得分:1)

我是否理解,客户是一个集合,Orders是一个集合,而State(显然)是一个属性?

var q = from a in Customer
    from b in a.Orders
    where b.ID == 2
              || b.ID == 3
    select b;

我会猜测。

修改

我做了类似的事情。确切地说我是怎么做的已经太久了,但我可以告诉你,我正在使用

public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values);

来自DynamicQueryable类。

this.CountrySitesObject.Sites.AsQueryable().Where(w.WhereQuery, w.WhereParameters) 

(从我的代码中复制)。

答案 4 :(得分:0)

如果您退一步询问客户想要做什么。

Filter bug information.

为什么不将数据导出为ex​​cel或将excel指向SQL表。构建它并不是那么有趣,但是你可以在几个小时内完成,而不是几天或几周。 :)