gpt4 book ai didi

entity-framework - 如何包含检查属性及其值的 And() 表达式

转载 作者:行者123 更新时间:2023-12-04 08:32:17 25 4
gpt4 key购买 nike

我想在我们的存储库中添加一个检查,以过滤出 companyId 上的所有对象(如果它存在并且与给定值匹配)。

所以我们有:

public T First<T>(Expression<Func<T, bool>> expression) where T : EntityObject  
{
var set = GetObjectSet<T>();
return set.FirstOrDefault<T>();
}

我想添加一行看起来像...

express.And("Check for CompanyId property if it exists then make sure it = 3");  

关于如何解决这个问题有什么想法吗?
谢谢 :)

最佳答案

如果您正在寻找一个函数,如果实体上存在公司 ID,您可以使用该函数将公司 ID 检查添加到您的表达式中,这应该可以解决问题:

public static Expression<Func<T, bool>> CheckPropertyIfExists<T, TProperty>(Expression<Func<T, bool>> expression, string propertyName, TProperty propertyValue)
{
Type type = typeof(T);
var property = type.GetProperty(propertyName, typeof(TProperty));
if(property == null || !property.CanRead)
return expression;

return expression.Update(
Expression.And( // &&
Expression.Equal( // ==
Expression.MakeMemberAccess(expression.Parameters[0], property), // T parameter.{propertyName}
Expression.Constant(propertyValue) // specified propertyValue constant
),
expression.Body // Original expression
),
expression.Parameters
);
}

你可以这样使用它:

public T First<T>(Expression<Func<T, bool>> expression, int companyId)
{
var set = GetObjectSet<T>();
return set.FirstOrDefault<T>(CheckPropertyIfExists(expression, "CompanyId", companyId));
}

现在您可以使用您的表达式和要过滤的 companyId 调用您的 First 方法。

一个稍微好一点的方法可能是将它用作过滤方法,即将它重写为不需要内部表达式并适用于对象查询(或 IQueryable)的扩展方法:

public static ObjectQuery<T> FilterByPropertyIfExists<T, TProperty>(this ObjectQuery<T> query, string propertyName, TProperty propertyValue)
{
Type type = typeof(T);
var property = type.GetProperty(propertyName, typeof(TProperty));
if(property == null || !property.CanRead)
return query;

var parameter = Expression.Parameter(typeof(T), "x");
Expression<Func<T, bool>> predicate = (Expression<Func<T, bool>>)Expression.Lambda(
Expression.Equal( // ==
Expression.MakeMemberAccess(parameter, property), // T parameter.{propertyName}
Expression.Constant(propertyValue) // specified propertyValue constant
),
parameter
);
return query.Where(predicate);
}

这样做的好处在于,它可以很好地与标准 LINQ 语法(查询语法和流畅语法)一起工作。

例如它允许这样的查询:

from x in repository.Clients.FilterByPropertyIfExists("Company", 5)
where x == ???
select x.Name;

[编辑]

我稍微清理了一下并添加了参数可见性检查(必须是公共(public)的静态属性)以及 ObjectQuery 实现(它将自动用于 ObjectQuery 和 ObjectSet):

public static class QueryExtensions
{
public static IQueryable<T> FilterByPropertyIfExists<T, TProperty>(this IQueryable<T> query, string propertyName, TProperty propertyValue)
{
Type type = typeof(T);
var property = type.GetProperty(
propertyName,
BindingFlags.Instance | BindingFlags.Public, // Must be a public instance property
null,
typeof(TProperty), // Must be of the correct return type
Type.EmptyTypes, // Can't have parameters
null
);
if (property == null || !property.CanRead) // Must exist and be readable
return query; // Return query unchanged

// Create a predicate to pass to the Where method
var parameter = Expression.Parameter(typeof(T), "it");
Expression<Func<T, bool>> predicate = (Expression<Func<T, bool>>)Expression.Lambda(
Expression.Equal( // ==
Expression.MakeMemberAccess(parameter, property), // T parameter.{propertyName}
Expression.Constant(propertyValue) // specified propertyValue constant
),
parameter
);
return query.Where(predicate); // Filter the query
}

public static ObjectQuery<T> FilterByPropertyIfExists<T, TProperty>(this ObjectQuery<T> query, string propertyName, TProperty propertyValue)
{
var filteredQuery = FilterByPropertyIfExists((IQueryable<T>)query, propertyName, propertyValue);
return (ObjectQuery<T>)filteredQuery; // Cast filtered query back to an ObjectQuery
}
}

关于entity-framework - 如何包含检查属性及其值的 And() 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4782001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com