[英]LINQ query to combine 2 resultsets
我有一個C#LINQ查詢,該查詢具有一個主查詢,然后根據變量是否未設置0進行其他2個查詢。
該查詢正在運行,但是我需要合並結果集並返回它。
我希望最終結果集包含兩個子查詢的結果組合。 有點像在SQL查詢中,您擁有:
SELECT * FROM myTable WHERE column1 = 'abc' OR column2 = 'xyz'
現在,我認為它使用的是AND而不是OR
var GeoLocations = rows.Select(r => new ElementSearchGeoLocation(r))
.Where(t => (t.GeoLocationType == "State" && t.CanViewState(t.GeoLocationState, user)) ||
(t.GeoLocationType == "City" && t.CanViewCity(t.GeoLocationCity, user)));
if(SystemList != 0)
{
GeoLocations = GeoLocations.Where(t => (dto.SystemList.Contains(t.SystemID)));
}
if (groupList != 0)
{
GeoLocations = GeoLocations.Where(t => (dto.groupList.Contains(t.PoliticalID)));
}
return Ok(GeoLocations);
有沒有辦法在LINQ中做到這一點?
這是PredicateBuilder
的實現,該實現能夠將兩個不同的表達式Or
在一起。
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var secondBody = expr2.Body.Replace(
expr2.Parameters[0], expr1.Parameters[0]);
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, secondBody), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var secondBody = expr2.Body.Replace(
expr2.Parameters[0], expr1.Parameters[0]);
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters);
}
}
能夠將一個表達式的所有實例替換為另一個表達式取決於以下代碼:
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
internal static class ExpressionExtensions
{
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
}
現在,您可以使用此代碼編寫:
var GeoLocations = rows.Select(r => new ElementSearchGeoLocation(r))
.Where(t => (t.GeoLocationType == "State" && t.CanViewState(t.GeoLocationState, user)) ||
(t.GeoLocationType == "City" && t.CanViewCity(t.GeoLocationCity, user)));
var predicate = PredicateBuilder.False();
if(SystemList != 0)
{
predicate = predicate.Or(t => dto.SystemList.Contains(t.SystemID));
}
if (groupList != 0)
{
predicate = predicate.Or(t => dto.groupList.Contains(t.PoliticalID));
}
return Ok(GeoLocations.Where(predicate));
使用Concat
添加其他行。 為了使代碼極少,我將存儲最初的“首先選擇”:
var AllLocations = rows.Select(r => new ElementSearchGeoLocation(r));
var mainQuery = AllLocations.Where(t => (t.GeoLocationType == "State" && t.CanViewState(t.GeoLocationState, user)) ||
(t.GeoLocationType == "City" && t.CanViewCity(t.GeoLocationCity, user)));
然后:
IEnumerable<GeoLocation> subQuery;
if (SystemList != 0)
subQuery = AllLocations.Where(...);
else
subQuery = AllLocations.Where(...);
var GeoLocations = mainQuery.Concat(subQuery);
如果您關心重復項,則可以在最后一步中使用Union
而不是Concat
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.