具有自定义表达式的Linq-SQL Generic GetById

时间:2016-07-06 12:10:35

标签: c# entity-framework linq-to-sql expression

我在我的数据库中创建了目标表的泛型。我还添加了一个通用的.where(),其中一个表达式在lambda表达式中只包含一个参数。有没有办法可以在同一个表达式中添加多个参数?请忽略以下方法返回1项的事实,我想让它返回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();
   }

我对此方法的实际意图是稍后在目标表“T”的“字符串”属性上执行Contains()。我想做类似下面的事情并附加到上面的表达式检查String属性是否包含“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();
   }

1 个答案:

答案 0 :(得分:1)

如果我理解正确,你正在寻找类似的东西:

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将结果与第一个条件组合。