gpt4 book ai didi

c# - 从枚举列表生成 Linq 或子句

转载 作者:行者123 更新时间:2023-11-30 13:47:17 25 4
gpt4 key购买 nike

问候溢出者,

我正在开发一个允许用户生成自定义报告的应用程序,我有一个场景需要从枚举值列表生成 Linq Or 子句。我遇到的问题是我看不到生成 Or 子句的优雅方式。

例如:

//Enumeration of possible 'OR' conditions
public enum Conditions
{
ByAlpha,
ByBeta,
ByGamma
}

//'Entity' I'm querying against.
class ResultObject
{
public bool AlphaValue { get; set; }
public bool BetaValue { get; set; }
public bool GammaValue { get; set; }
public string Name { get; set; }
}

class Program
{
static void Main(string[] args)
{
//Create list of desired conditions.
//Basically I want this to mimic the query,
// "Show me all of the ResultObjects where the AlphaValue is true or the GammaValue is true".
var conditions = new List<Conditions>
{
Conditions.ByAlpha,
Conditions.ByGamma
};

//Sample collection of objects. This would normally be a collection of EF entities.
var sampleCollection = new List<ResultObject>
{
new ResultObject
{
Name = "Sample 1",
AlphaValue = true,
BetaValue = true,
GammaValue = true,
},
new ResultObject
{
Name = "Sample 2",
AlphaValue = false,
BetaValue = false,
GammaValue = false,
},
new ResultObject
{
Name = "Sample 3",
AlphaValue = true,
BetaValue = false,
GammaValue = true,
}
};

var sampleCollectionQueryable = sampleCollection.AsQueryable();

//This should filter the sampleCollection down to containing only the
//"Sample 3" ResultObject; instead, it filters out all of the ResultObjects.
var query = GenerateOrClause(sampleCollectionQueryable, conditions);
}

static IQueryable<ResultObject> GenerateOrClause(IQueryable<ResultObject> query, List<Conditions> conditions)
{
//This approach generates a series of AND statements, instead I need a series of OR statements
//for each condition.
foreach (var condition in conditions)
{
switch (condition)
{
case Conditions.ByAlpha:
query = query.Where(x => x.AlphaValue);
break;
case Conditions.ByBeta:
query = query.Where(x => x.BetaValue);
break;
case Conditions.ByGamma:
query = query.Where(x => x.GammaValue);
break;
default:
throw new ArgumentOutOfRangeException();
}
}

return query;
}
}

有什么想法吗?

最佳答案

你应该使 Conditions 成为 Flags 枚举:

[Flags]
public enum Conditions {
ByNone = 0,
ByAlpha = 1,
ByBeta = 2,
ByGamma = 4
}

并更改您的 ResultObject:

class ResultObject {
public Conditions Conditions { get; set; }
public string Name { get; set; }
}

然后你可以说:

var conditions = new List<Conditions> { Conditions.ByAlpha, Conditions.ByGamma };
var matches = sampleCollection
.Where(x => conditions.Select(c => c & x != 0).Any());

您要解决的问题的正确设计。

如果出于某种原因您需要保留当前的 ​​ResultObject,为了清楚起见,我现在将其称为 OldResultObject:

class OldResultObject {
public bool AlphaValue { get; set; }
public bool BetaValue { get; set; }
public bool GammaValue { get; set; }
public string Name { get; set; }
}

将其投影到新的 ResultObject 很容易:

var resultObject = new ResultObject {
Conditions =
(oldResultObject.AlphaValue ? Conditions.ByAlpha : Conditions.ByNone) |
(oldResultObject.BetaValue ? Conditions.ByBeta : Conditions.ByNone) |
(oldResultObject.GammaValue ? Conditions.ByGamma : Conditions.ByNone),
Name = oldResult.Name;
}

因此,您在重新设计方面确实非常付出了很少的努力。

关于c# - 从枚举列表生成 Linq 或子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17971405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com