使用 SQL 服务器在 asp.NET 中查询动态
Querying dynamic in asp.NET with SQL server
(如果标题不能代表这个问题请说明,我想不出一个好的简短描述)
我正在尝试为我的 Web 应用程序实现高级搜索功能。此搜索必须能够搜索很多可能的组合。
如图所示,每个组(AND 或 OR)可以有另一个组或条件,可以相等或不相等。图片应生成如下所示的 where 子句:
WHERE (Application like '%User%' AND Host not like '%fjzhykjety%') OR (REMOTE_HOST like '%uykirlyy%' AND REMOTE_PORT not like '%55555%')
Application、Host 和 REMOTE_HOST 是字符串,REMOTE_PORT 是可为 null 的 int。我还有一个必须可搜索的 GUID。
目前这个前端搜索是用 angular 编写的,并为我提供了以下 json(json 取决于嵌套组和条件)的示例:
{
"group": {
"operator": "OR",
"rules": [
{
"group": {
"operator": "AND",
"rules": [
{
"condition": "=",
"field": {
"name": "Application",
"type": "select"
},
"data": "User"
},
{
"condition": "<>",
"field": {
"name": "Host",
"type": "text"
},
"data": "fjzhykjety"
}
]
}
},
{
"group": {
"operator": "AND",
"rules": [
{
"condition": "=",
"field": {
"name": "REMOTE_HOST",
"type": "text"
},
"data": "uykirlyy"
},
{
"condition": "<>",
"field": {
"name": "REMOTE_PORT",
"type": "number"
},
"data": 55555
}
]
}
}
]
}
}
我需要一种方法将此数据发送到我的 .NET 应用程序(使用 REST API)并在数据库中查询它。我研究了动态 linq 以进行查询,但由于 json 文件的格式并不总是相同,因此很难在 C# 中为其创建 class 并为此搜索构建动态 linq 查询.
实施此高级搜索的最佳方法是什么?
这里是一个动态查询的例子。你也可以结合你的查询 linqkit 是很好的谓词构建器。
http://www.albahari.com/nutshell/linqkit.aspx
https://github.com/scottksmith95/LINQKit
public List<CustomerPointsDetail> GetCustomerPointsDetails(
int customerId,
int? catalogRewardId = null,
long? couponId = null,
long? transactionId = null,
CustomerPointsDetailStatus? inStatus = null,
CustomerPointsDetailStatus? notInStatus = null,
bool? isPointsGreaterThanZero = null,
bool? isRemainingPointsGreaterThanZero = null,
CustomerPointsDetailOperationType? operationType = null,
DateTime? startDate = null,
DateTime? endDate = null,
bool isExpiredRecordsIncluded = false)
{
var query = this.customerPointsDetailRepository.Table.Where(cpd => cpd.CustomerId == customerId);
if (catalogRewardId.HasValue)
{
query = query.Where(cpd => cpd.CatalogRewardId == catalogRewardId);
}
if (couponId.HasValue)
{
query = query.Where(cpd => cpd.CouponId == couponId);
}
if (transactionId.HasValue)
{
query = query.Where(cpd => cpd.TransactionId == transactionId);
}
if (inStatus.HasValue)
{
query = query.Where(cpd => cpd.Status == inStatus);
}
if (notInStatus.HasValue)
{
query = query.Where(cpd => cpd.Status != notInStatus);
}
if (isRemainingPointsGreaterThanZero.HasValue)
{
if (isRemainingPointsGreaterThanZero.GetValueOrDefault())
{
query = query.Where(cpd => cpd.RemainingPoints.HasValue && cpd.RemainingPoints > 0);
}
else
{
query = query.Where(cpd => cpd.RemainingPoints.HasValue && cpd.RemainingPoints < 0);
}
}
if (isPointsGreaterThanZero.HasValue)
{
if (isPointsGreaterThanZero.GetValueOrDefault())
{
query = query.Where(cpd => cpd.Points > 0);
}
else
{
query = query.Where(cpd => cpd.Points < 0);
}
}
if (operationType.HasValue)
{
query = query.Where(cpd => cpd.OperationType == operationType);
}
if (!isExpiredRecordsIncluded)
{
query = query.Where(cpd => !cpd.PointsExpireDate.HasValue
|| (cpd.PointsExpireDate.HasValue && cpd.PointsExpireDate > DateTime.Now));
}
if (startDate.HasValue)
{
query = query.Where(cpd => cpd.CreateDate >= startDate);
}
if (endDate.HasValue)
{
query = query.Where(cpd => cpd.CreateDate <= endDate);
}
query = query.OrderBy(cpd => cpd.PointsExpireDate);
return query.ToList();
}
这里是 Linqkit 示例
IQueryable<Product> SearchProducts (params string[] keywords)
{
var predicate = PredicateBuilder.False<Product>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or (p => p.Description.Contains (temp));
}
return dataContext.Products.Where (predicate);
}
编辑
您需要一个表达式来给出您的方法和。可以结合Linqkit。
Expression<Func<Product, bool>> e1 = DynamicExpression.ParseLambda<Product, bool>("Type= \"Type_A\"");
OR
Expression<Func<Product, bool>> e1 = p => p.Type="Type_A";
在程序中调用 SearchProduct 之前
var expressions = new Dictionary<Expression<Func<Product, bool>>, bool>();
Expression<Func<Product, bool>> e1 = p => p.Type="Type_A";
Expression<Func<Product, bool>> e2 = p => p.Type="Type_B";
expressions.Add(e1,true);
expressions.Add(e2,true);
SearchProducts(expressions); //send expression list for evoluate
IQueryable<Product> SearchProducts (Dictionary<Expression<Func<Product, bool>>, bool> expressionList)
{
var predicate = PredicateBuilder.False<Product>();
foreach(expression in expressionList)
{
if(expression.Value) // AND
{
predicate = predicate.And(expression.Key);
}else // OR
{
predicate = predicate.Or(expression.Key);
}
}
.
.
}
(如果标题不能代表这个问题请说明,我想不出一个好的简短描述)
我正在尝试为我的 Web 应用程序实现高级搜索功能。此搜索必须能够搜索很多可能的组合。
如图所示,每个组(AND 或 OR)可以有另一个组或条件,可以相等或不相等。图片应生成如下所示的 where 子句:
WHERE (Application like '%User%' AND Host not like '%fjzhykjety%') OR (REMOTE_HOST like '%uykirlyy%' AND REMOTE_PORT not like '%55555%')
Application、Host 和 REMOTE_HOST 是字符串,REMOTE_PORT 是可为 null 的 int。我还有一个必须可搜索的 GUID。
目前这个前端搜索是用 angular 编写的,并为我提供了以下 json(json 取决于嵌套组和条件)的示例:
{
"group": {
"operator": "OR",
"rules": [
{
"group": {
"operator": "AND",
"rules": [
{
"condition": "=",
"field": {
"name": "Application",
"type": "select"
},
"data": "User"
},
{
"condition": "<>",
"field": {
"name": "Host",
"type": "text"
},
"data": "fjzhykjety"
}
]
}
},
{
"group": {
"operator": "AND",
"rules": [
{
"condition": "=",
"field": {
"name": "REMOTE_HOST",
"type": "text"
},
"data": "uykirlyy"
},
{
"condition": "<>",
"field": {
"name": "REMOTE_PORT",
"type": "number"
},
"data": 55555
}
]
}
}
]
}
}
我需要一种方法将此数据发送到我的 .NET 应用程序(使用 REST API)并在数据库中查询它。我研究了动态 linq 以进行查询,但由于 json 文件的格式并不总是相同,因此很难在 C# 中为其创建 class 并为此搜索构建动态 linq 查询.
实施此高级搜索的最佳方法是什么?
这里是一个动态查询的例子。你也可以结合你的查询 linqkit 是很好的谓词构建器。
http://www.albahari.com/nutshell/linqkit.aspx https://github.com/scottksmith95/LINQKit
public List<CustomerPointsDetail> GetCustomerPointsDetails(
int customerId,
int? catalogRewardId = null,
long? couponId = null,
long? transactionId = null,
CustomerPointsDetailStatus? inStatus = null,
CustomerPointsDetailStatus? notInStatus = null,
bool? isPointsGreaterThanZero = null,
bool? isRemainingPointsGreaterThanZero = null,
CustomerPointsDetailOperationType? operationType = null,
DateTime? startDate = null,
DateTime? endDate = null,
bool isExpiredRecordsIncluded = false)
{
var query = this.customerPointsDetailRepository.Table.Where(cpd => cpd.CustomerId == customerId);
if (catalogRewardId.HasValue)
{
query = query.Where(cpd => cpd.CatalogRewardId == catalogRewardId);
}
if (couponId.HasValue)
{
query = query.Where(cpd => cpd.CouponId == couponId);
}
if (transactionId.HasValue)
{
query = query.Where(cpd => cpd.TransactionId == transactionId);
}
if (inStatus.HasValue)
{
query = query.Where(cpd => cpd.Status == inStatus);
}
if (notInStatus.HasValue)
{
query = query.Where(cpd => cpd.Status != notInStatus);
}
if (isRemainingPointsGreaterThanZero.HasValue)
{
if (isRemainingPointsGreaterThanZero.GetValueOrDefault())
{
query = query.Where(cpd => cpd.RemainingPoints.HasValue && cpd.RemainingPoints > 0);
}
else
{
query = query.Where(cpd => cpd.RemainingPoints.HasValue && cpd.RemainingPoints < 0);
}
}
if (isPointsGreaterThanZero.HasValue)
{
if (isPointsGreaterThanZero.GetValueOrDefault())
{
query = query.Where(cpd => cpd.Points > 0);
}
else
{
query = query.Where(cpd => cpd.Points < 0);
}
}
if (operationType.HasValue)
{
query = query.Where(cpd => cpd.OperationType == operationType);
}
if (!isExpiredRecordsIncluded)
{
query = query.Where(cpd => !cpd.PointsExpireDate.HasValue
|| (cpd.PointsExpireDate.HasValue && cpd.PointsExpireDate > DateTime.Now));
}
if (startDate.HasValue)
{
query = query.Where(cpd => cpd.CreateDate >= startDate);
}
if (endDate.HasValue)
{
query = query.Where(cpd => cpd.CreateDate <= endDate);
}
query = query.OrderBy(cpd => cpd.PointsExpireDate);
return query.ToList();
}
这里是 Linqkit 示例
IQueryable<Product> SearchProducts (params string[] keywords)
{
var predicate = PredicateBuilder.False<Product>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or (p => p.Description.Contains (temp));
}
return dataContext.Products.Where (predicate);
}
编辑
您需要一个表达式来给出您的方法和。可以结合Linqkit。
Expression<Func<Product, bool>> e1 = DynamicExpression.ParseLambda<Product, bool>("Type= \"Type_A\"");
OR
Expression<Func<Product, bool>> e1 = p => p.Type="Type_A";
在程序中调用 SearchProduct 之前
var expressions = new Dictionary<Expression<Func<Product, bool>>, bool>();
Expression<Func<Product, bool>> e1 = p => p.Type="Type_A";
Expression<Func<Product, bool>> e2 = p => p.Type="Type_B";
expressions.Add(e1,true);
expressions.Add(e2,true);
SearchProducts(expressions); //send expression list for evoluate
IQueryable<Product> SearchProducts (Dictionary<Expression<Func<Product, bool>>, bool> expressionList)
{
var predicate = PredicateBuilder.False<Product>();
foreach(expression in expressionList)
{
if(expression.Value) // AND
{
predicate = predicate.And(expression.Key);
}else // OR
{
predicate = predicate.Or(expression.Key);
}
}
.
.
}