Я пытаюсь создать универсальный класс команд Exists (), который может создать предложение where для ЛЮБОЙ комбинации открытых свойств (полей) ЛЮБОГО класса LinqToSQL (таблиц) в моем тексте данных (базе данных).
Если вы написали следующее на основе фрагментов из MSDN и обнаружили, что я не могу успешно выполнить код, если я не объявил явно тип сущности (в данном случае MyApp.Data.Organization) Expression.Lambdaпараметр выражения Expression.Call.
Другими словами,
Expression.Lambda<Func<tblType,bool>>(predBody, new ParameterExpression[] { pe }));
не работает, но
Expression.Lambda<Func<MyApp.Data.Organization,bool>>(predBody, new ParameterExpression[] { pe }));
работает.Я хочу что-то похожее на первое, поэтому метод остается общим для всех классов LinqToSQL в моем контексте данных.
Я проверил, что весь код до оператора Expression.Call работает нормально и генерирует правильный предикат.Что мне нужно изменить, чтобы сохранить параметр Type универсальным, чтобы тот же код работал для любого класса LinqToSQL в контексте данных?
Revision for Clarity Кажется, я используюT как переменная сбивала с толку.Вот пересмотренный код:
OrganizationCriteria criteria = new OrganizationCriteria { OrganizationId = 2 };
using (var ctx = ContextManager<MyApp.Data.MyAppDataContext>.GetManager(myConnectionString, false)) {
IQueryable tbl = ctx.DataContext.GetTable(criteria.EntityType).AsQueryable();
Type tblType = tbl.ElementType;
ParameterExpression pe = Expression.Parameter( tblType, "Item" );
Expression left;
Expression right;
Expression prev = null;
Expression curr = null;
Expression predBody = null;
foreach ( KeyValuePair<string, object> kvp in criteria.StateBag ) {
prev = curr;
object val = kvp.Value;
if (val is System.String ) {
left = Expression.Call( pe, typeof( string ).GetMethod( "ToLower", System.Type.EmptyTypes ) );
right = Expression.Constant( kvp.Value.ToString() );
}
else {
left = Expression.Property( pe, tblType.GetProperty( kvp.Key ) );
right = Expression.Constant( kvp.Value, tblType.GetProperty( kvp.Key ).PropertyType );
}
curr = Expression.Equal( left, right );
if ( prev != null ) {
predBody = Expression.AndAlso( prev, curr );
}
else {
predBody = curr;
}
}
MethodCallExpression whereCall = Expression.Call(
typeof( Queryable ),
"Where",
new Type[] { tblType },
tbl.Expression,
Expression.Lambda<Func<tblType,bool>>(predBody, new ParameterExpression[] { pe }));
var results = tbl.Provider.CreateQuery( whereCall );
}