Linq-SQL 带有自定义表达式的通用 GetById
Linq-SQL Generic GetById with a custom Expression
我在我的数据库中创建了一个通用目标 tables。我还添加了一个通用的 .where() ,其表达式在 lambda 表达式中仅包含 1 个参数。有没有一种方法可以在同一个表达式中添加多个参数?请忽略下面的方法 returns 1 item,我想让它 return a IList.
这是我的方法:
public virtual T GetById( Int32 id, String someStringColumn )
{
ParameterExpression itemParameter = Expression.Parameter( typeof( T ), "item" );
var whereExpression = Expression.Lambda<Func<T, Boolean>>
(
Expression.Equal( Expression.Property( itemParameter, "Id" ), Expression.Constant( id ) ),
new[] { itemParameter }
);
return context.Set<T>().Where( whereExpression ).FirstOrDefault();
}
我对该方法的实际意图是稍后对目标 table "T" 的 "string" 属性执行 Contains()。我想做类似下面的事情并附加到上面的表达式检查字符串 属性 是否包含 "someStringColumn" 中的值。只是一个见解,"someStringColumn" 将是我页面上的一般搜索字符串,在每次后端调用时都经过 Ajax。
var properties = item.GetType().GetProperties().Where( p => p.PropertyType == typeof( string ) ).ToArray();
for ( Int32 i = 0; i < properties.Length; i++ )
{
}
我正在尝试通过非泛型方法实现类似的目标:
public override List<TableInDatabase> List( PagingModel pm, CustomSearchModel csm )
{
String[] qs = ( pm.Query ?? "" ).Split( ' ' );
return context.TableInDatabase
.Where( t => ( qs.Any( q => q != "" ) ? qs.Contains( t.ColumnName) : true ) )
.OrderBy( String.Format( "{0} {1}", pm.SortBy, pm.Sort ) )
.Skip( pm.Skip )
.Take( pm.Take )
.ToList();
}
如果我没理解错的话,你正在寻找这样的东西:
var item = Expression.Parameter(typeof(T), "item");
Expression body = Expression.Equal(Expression.Property(item, "Id"), Expression.Constant(id));
if (!string.IsNullOrEmpty(someStringColumn))
{
var properties = typeof(T).GetProperties().Where(p => p.PropertyType == typeof(string)).ToList();
if (properties.Any())
body = Expression.AndAlso(body,
properties.Select(p => (Expression)Expression.Call(
Expression.Property(item, p), "Contains", Type.EmptyTypes, Expression.Constant(someStringColumn))
).Aggregate(Expression.OrElse));
}
var whereExpression = Expression.Lambda<Func<T, bool>>(body, item);
即为每个字符串 属性 构建 Contains
表达式,使用 Or
组合它们,最后使用 And
.
将结果与第一个条件组合
我在我的数据库中创建了一个通用目标 tables。我还添加了一个通用的 .where() ,其表达式在 lambda 表达式中仅包含 1 个参数。有没有一种方法可以在同一个表达式中添加多个参数?请忽略下面的方法 returns 1 item,我想让它 return a IList.
这是我的方法:
public virtual T GetById( Int32 id, String someStringColumn )
{
ParameterExpression itemParameter = Expression.Parameter( typeof( T ), "item" );
var whereExpression = Expression.Lambda<Func<T, Boolean>>
(
Expression.Equal( Expression.Property( itemParameter, "Id" ), Expression.Constant( id ) ),
new[] { itemParameter }
);
return context.Set<T>().Where( whereExpression ).FirstOrDefault();
}
我对该方法的实际意图是稍后对目标 table "T" 的 "string" 属性执行 Contains()。我想做类似下面的事情并附加到上面的表达式检查字符串 属性 是否包含 "someStringColumn" 中的值。只是一个见解,"someStringColumn" 将是我页面上的一般搜索字符串,在每次后端调用时都经过 Ajax。
var properties = item.GetType().GetProperties().Where( p => p.PropertyType == typeof( string ) ).ToArray();
for ( Int32 i = 0; i < properties.Length; i++ )
{
}
我正在尝试通过非泛型方法实现类似的目标:
public override List<TableInDatabase> List( PagingModel pm, CustomSearchModel csm )
{
String[] qs = ( pm.Query ?? "" ).Split( ' ' );
return context.TableInDatabase
.Where( t => ( qs.Any( q => q != "" ) ? qs.Contains( t.ColumnName) : true ) )
.OrderBy( String.Format( "{0} {1}", pm.SortBy, pm.Sort ) )
.Skip( pm.Skip )
.Take( pm.Take )
.ToList();
}
如果我没理解错的话,你正在寻找这样的东西:
var item = Expression.Parameter(typeof(T), "item");
Expression body = Expression.Equal(Expression.Property(item, "Id"), Expression.Constant(id));
if (!string.IsNullOrEmpty(someStringColumn))
{
var properties = typeof(T).GetProperties().Where(p => p.PropertyType == typeof(string)).ToList();
if (properties.Any())
body = Expression.AndAlso(body,
properties.Select(p => (Expression)Expression.Call(
Expression.Property(item, p), "Contains", Type.EmptyTypes, Expression.Constant(someStringColumn))
).Aggregate(Expression.OrElse));
}
var whereExpression = Expression.Lambda<Func<T, bool>>(body, item);
即为每个字符串 属性 构建 Contains
表达式,使用 Or
组合它们,最后使用 And
.