我有一个项目要求我做这么大的搜索引擎,但这一切都是动态的。我的意思是我可以拥有大约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个“可能”添加的内容可供搜索...任何想法?
答案 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.
为什么不将数据导出为excel或将excel指向SQL表。构建它并不是那么有趣,但是你可以在几个小时内完成,而不是几天或几周。 :)