如何在LINQ中创建动态选择表达式?
作者:互联网
我目前所拥有的看起来像这样:
if(userLikesBananas)
{
return from fruit in basket
select new Fruit
{
AteBanana = Bowl.Any(b => b.OwnedBy == user && b.Contains(fruit) && fruit.Type == FruitType.Banana),
...
...
//lots of properties
...
}
}
else
{
return from fruit in basket
select new Fruit
{
AteBanana = Bowl.Any(b => b.Contains(fruit)),
...
...
//lots of properties
...
}
}
诚然,该示例完全没有意义,但原理是我想根据任意准则更改属性选择的条件.现在,将重复执行select语句.
现在到了我需要添加依赖注释者的条件的时候了.我不想在4种不同的情况下,物业条件略有不同.
我想做的是这样的:
Func<Fruit, bool> fruitFunc = f => false;
if(userLikesBananas)
{
fruitFunc = f => Bowl.Any(b => b.OwnedBy == user && b.Contains(f) && f.Type == FruitType.Banana);
}
else
{
fruitFunc = f => Bowl.Any(b => b.Contains(f));
}
return from fruit in basket
select new Fruit
{
AteBanana = fruitFunc(fruit)
...
...
//lots of properties
...
};
问题在于表达式不能转换为sql,因为它包含动态调用.我曾尝试将Func包装在Expression中,但似乎会出现相同的问题.
所以问题是,如何避免复制和粘贴?
解决方法:
…我的英语不好,但我会尽力解释如何轻松解决此问题:-)
Dynamic Linq不利于类型控制-易于使用,但是您无法浏览结果对象(x.Name,x.Surname等)
有一个(小菜鸟般的)技巧来解决这个问题(我正在使用它,并且很容易理解):
>使用您要选择的对象的属性创建枚举.
公共枚举MyAtrs {ID,名字,姓氏}
>创建Dictionary< MyAtrs,bool> (并填写)条件(如果要获取此属性,请设置为true)
公共字典Dic = new Dictionary();
Dic.Add(MyAtrs.ID,true);
Dic.Add(MyAtrs.Firstname,false);
Dic.Add(MyAtrs.Surname,true);
>建立查询:
var query = DBContext.MyDBTable.Where(predicate).Select(e => new {
ID = Dic [MyAtrs.ID]? e.dbID:0,
名= Dic [MyAtrs.Firstname]? e.dbFirstname:null,
姓= Dic [MyAtrs.Surname]? e.dbSurname:null,
});
在这种情况下,SQL Select语句中将包含所有3列,但只有几个字节(重要的是…). SQL Server会退回所有3列,但是(在这种情况下)Firstname将为空(例如{ID = 123,Firstname =,Surname =“ Jobs”}).
这不是很出色,但是它是在不丢失类型控制的情况下如何构建“动态”选择表达式的简便方法:)
标签:dynamic,linq-to-sql,linq,c 来源: https://codeday.me/bug/20191209/2097793.html