我经常有这样的代码:
var stRecs = db.<someTable>
.Where(a => a.DepID == depID)
选择单个记录,但是如果 depID == 0
我想取回所有记录。
我正在考虑创建一个扩展方法“WhereDepID_OrAll”,比如
public static IQueryable<T> WhereDepID_OrAll<T>(this IQueryable<T> source)
where T: // is what?
{
if(depID > 0) { return source.Where(a => a.depID == depID); }
else return source.Where(a => a);
}
现在我的基本问题是:
我有几个带有 depID 的表 - 如何设置 Where T:
?
该方法将如何确定表是否具有 depID?
解决根本问题的更好方法?
最佳答案
乍一看, react 是:创建一个接口(interface)
public interface ObjectWithDepartmentInterface {
int depID;
}
让所有使用这个depId的实体实现这个接口(interface),并使用
where T : ObjectWithDepartmentInterface
但 linq to entities 不接受查询中接口(interface)的属性...参见示例:Expression generated based on interface
因此,唯一的方法是使您的实体具有从具有 depId 属性的公共(public)实体(可能是抽象的)继承的 depId。
并使用这个抽象实体作为
where T:
一种更简单(但更丑陋)的方法可能是不在 T 上添加约束,在方法中构建谓词,并在不好的情况下抛出异常。
if (typeof(T).GetProperty("depId") == null)
throw InvalidOperationException (string.Format("{0}" doesn't have a depId property, typeof(T).Name))
编辑
但也许这不是depId作为公共(public)属性的问题 然后
public static IQueryable<T> WhereExistsOrAll<T>(this IQueryable<T> source, string propertyName, int value)
where T: // is what?
{
if (value == 0)
return source;
var parameter = Expression.Parameter(typeof(T), "m");
Expression member = parameter;
member = Expression.Property(member, propertyName);
member = Expression.Equals(member, Expression.Constant(value));
var lambda = Expression.Lambda<Func<T, bool>>(member, new[]{parameter});
return source.Where(lambda);
}
用法
var stRecs = db.<someTable>.WhereExistsOrAll("depId", depId);
编辑 2
另一种方法是解析谓词以获取“常量”值
类似的东西
public static IQueryable<T> GetAllOrRestrict<T>(this IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
{
var expression = predicate.Body as BinaryExpression;
var rightPart = expression.Right as MemberExpression;
var value = GetValue(rightPart);
var test = value.ToString();
int val;
if (Int32.TryParse(value.ToString(), out val))
{
if (val != 0)
return queryable.Where(predicate);
}
return queryable;
}
private static object GetValue(MemberExpression member)
{
var objectMember = Expression.Convert(member, typeof(object));
var getterLambda = Expression.Lambda<Func<object>>(objectMember);
var getter = getterLambda.Compile();
return getter();
}
用法
var stRecs = db.<someTable>.GetAllOrRestrict(m => m.depID == depId);
关于c# - 如何检查扩展方法中类型中是否存在属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16730824/