如何使用where in
定义Dynamic Linq
条件?
我在下面厌倦了解决方法,但它一定不行,因为它没有意义!
context.Records.Where("@0.Contains(ID)", new object[]{
new string[] {"1", "2", "3"}
}); // throws error No property or field 'ID' exists in type 'String'
修改1:
感谢大家,您只需在it
查询中使用outerIt
或Dynamic.Linq
关键字,因此在我的示例中,我只需要使用outerIt
:< / p>
context.Records.Where("@0.Contains(outerIt.ID)", new object[]{
new string[] {"1", "2", "3"}
});
您可以在此处找到更多示例和信息:Advanced Linq - Dynamic Linq query library: Add support for 'Contains' extension
答案 0 :(得分:2)
如果使用EF,可以使用直接sql命令,例如:
context.Database.ExecuteSqlCommand($"SELECT * FROM Records AS r WHERE r.{dynamicPropertyName} IN @ids", new string[] {"1", "2", "3"});
修改强>
解决:
System.Linq.Dynamic - Can I use IN clause in WHERE statement
答案 1 :(得分:2)
您可以通过创建一个简单的扩展方法轻松获得相同的结果:
public static class Utils
{
public static bool In<T>(this T src, params T[] items)
{
return items.Contains(src);
}
}
然后像这样称呼它:
context.Records.Where(record => record.In("1", "2", "3"));
答案 2 :(得分:2)
您可以编写自己的扩展方法In
,这里是IEnumerable:
public static class ExtLinq
{
public static IEnumerable<TSource> In<TSource, TMember>(this IEnumerable<TSource> source,
Func<TSource, TMember> identifier, params TMember[] values) =>
source.Where(m => values.Contains(identifier(m)));
}
像这样使用它:
context.Records.In(x => x.ID, 1, 2, 3)
如果您希望在服务器上执行IN
以保存数据传输,请使用此IQueryable版本,使用表达式API实现:
public static IQueryable<TSource> In<TSource, TMember>(this IQueryable<TSource> source,
Expression<Func<TSource, TMember>> identifier, params TMember[] values)
{
var parameter = Expression.Parameter(typeof(TSource), "m");
var inExpression = GetExpression(parameter, identifier, values);
var theExpression = Expression.Lambda<Func<TSource, bool>>(inExpression, parameter);
return source.Where(theExpression);
}
static Expression GetExpression<TSource, TMember>(ParameterExpression parameter, Expression<Func<TSource, TMember>> identifier, IEnumerable<TMember> values)
{
var memberName = (identifier.Body as MemberExpression).Member.Name;
var member = Expression.Property(parameter, memberName);
var valuesConstant = Expression.Constant(values.ToList());
MethodInfo method = typeof(List<TMember>).GetMethod("Contains");
Expression call = Expression.Call(valuesConstant, method, member);
return call;
}
此查询(或类似的取决于您的表)将在服务器上执行并返回所需的数据:
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name]
FROM [dbo].[Records] AS [Extent1]
WHERE [Extent1].[ID] IN (1, 2, 3)
答案 3 :(得分:2)
其他人在这里介绍了有趣的解决方法,但如果我们使用Dynamic.Linq
库则它们没用。 Oleksandr Nahirniak found this question on Stackoverflow。还有一篇关于使用Dynamic.Linq
审核here的高级Linq查询的博文。
自版本1.0.4
以来,该库也支持Contains
扩展。它可以像下面这样完成:
query = Contact.GetContactsList()
.AsQueryable()
.Where("@0.Contains(outerIt.Country)", new List<String>() { "Austria", "Poland" });
或
query = Contact.GetContactsList()
.AsQueryable()
.Where("@0.Contains(outerIt.Country) && it.BirthDate.Year > @1", new List<string>() { "Austria", "Poland" }, 1955);
有两个关键字it
和outerIt
。它表示您已作为参数传递的列表,outerIt
表示集合本身。
所以这是我的工作范例:
context.Records.Where("@0.Contains(outerIt.ID)", new object[]{
new string[] {"1", "2", "3"}
});