其中LINQ具有多输入和多字段

时间:2017-01-03 07:34:06

标签: c# linq enums

我有一个API,其中包含一个包含枚举列表的请求参数。对应每个枚举是表中的每个字段。你们可以看看这个:

public enum Type {
   a,
   b,
   c
}

在实体中我有这个:

....
public boolean is_a {get; set;}
public boolean is_b {get; set;}
public boolean is_c {get; set;}

所以我的目的是:当我提交枚举列表是[a,b]时,我可以有一个查询,可以查看Where方法来查找记录is_a = true或记录有{{ 1}} =真。 还有一件事,只有三个字段is_bis_ais_b中的一个。

更新 只是为了更多细节。我给你们这个我的请求param就像这样:

is_c

我希望在此参数中使用public class RequestParam { public string id; public List<Type> types; } 进行查询。

3 个答案:

答案 0 :(得分:4)

如果我假设你的实体类型被称为Entity并且你有一个entities的列表,那么这对我有用:

var check = new Dictionary<Type, Func<Entity, bool>>()
{
    { Type.a, entity => entity.is_a },
    { Type.b, entity => entity.is_b },
    { Type.c, entity => entity.is_c },
};

var entities = new List<Entity>(); /* populated somehow */

var types = new [] { Type.a, Type.b };

var query =
    from entity in entities
    where types.Any(type => check[type](entity))
    /* use `.All` if you want all props to be true */
    select entity;

答案 1 :(得分:1)

使用正确的工具完成工作。

不使用枚举集合(类型为Integer)来浪费内存,而只使用一个整数来保存多于一个枚举值。使用FlagsAttrbute定义枚举,并将枚举值设置为2的幂。

[FlagsAttribute] 
public enum MyType 
{
    a = 1,
    b = 2,
    c = 4,
    d = 8
}

public class Item
{
    public string Id { get; set; }
    public MyType Type { get; set; }
}

然后您可以添加MyType枚举

的值
var typeItem = new Item();   
typeItem.Type |= MyType.c;
typeItem.Type |= MyType.d;

并使用.HasFlag()方法检查值是否包含特定的枚举值

var selected = items.Where(item => item.Type.HasFlag(MyType.a) ||
                                   item.Type.HasFlag(MyType.b) ||
                                   item.Type.HasFlag(MyType.c));
// use selected values

或使用按位运算符&进行更有效的比较

MyType requiredTypes = MyType.a | MyType.b | MyType.c; // as integer it equals 7

var items = new[]
{
    new Item { Id = "1", Type = MyType.a | MyType.b},
    new Item { Id = "2", Type = MyType.a | MyType.b | MyType.c},
    new Item { Id = "3", Type = MyType.a},
    new Item { Id = "4", Type = MyType.d}       
}
const int REQUIRED_TYPES = 7;
var selected = items.Where(item => ((int)item.Type & REQUIRED_TYPES) > 0);
// will return items with Ids
// 1, 2, 3

然后,您可以使用一个

而不是三个布尔属性
public class Item
{
    public string Id { get; set; }
    public MyType Type { get; set; }
    public bool IsValid
    {
        get
        {
            const int REQUIRED_TYPES = 7;
            var result = (int)item.Type & REQUIRED_TYPES;
            return result > 0;
        }
    }

    // You can make adding types in more readable way
    public void AddType(MyType type)
    {
        Type |= type;
    }
}

您仍然可以使用.HasFlag方法检查是否设置了某个特定标志

var item = new Item();
item.AddType(MyType.c);

if (item.Type.HasFlag(MyType.c))
{

}

答案 2 :(得分:1)

经过一段时间的研究,我发现我们可以使用Linqkit构建动态查询:

var searchQuery = PredicateBuilder.New<YourModel>();

  foreach (Type item in searchParams.types)
            {
                switch (item)
                {
                    case Type.a:
                        searchQuery = searchQuery.Or(e => e.is_a);
                        //query = query.Where(e => e.is_pro);
                        break;
                    case Type.b:
                        searchQuery = searchQuery.Or(e => e.is_b);
                        break;
                    case Type.c:
                        searchQuery = searchQuery.Or(e => e.is_c);
                        break;
                    default:
                        break;
                }
            }

            query = query.AsExpandable().Where(searchQuery);