动态Linq在哪里IN

时间:2018-04-01 19:16:14

标签: c# linq dynamic-linq

如何使用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查询中使用outerItDynamic.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

4 个答案:

答案 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);

有两个关键字itouterIt。它表示您已作为参数传递的列表,outerIt表示集合本身。

所以这是我的工作范例:

context.Records.Where("@0.Contains(outerIt.ID)", new object[]{
   new string[] {"1", "2", "3"}
});