重用 LINQ To Entities 语句
Reuse a LINQ To Entities statement
我有以下 Select
表达式将在数据库端执行:
var model = new ProductListViewModel()
{
Products = products
.Select(q => new ProductViewModel()
{
// Other mapping
Name = q.LanguageKey.LanguageValues.FirstOrDefault(p => p.LanguageKeyID == currentLanguageID && p.Active).Value,
})
.OrderBy(q => q.Name)
};
如您所见,名称部分很长,我程序的其他部分也使用相同的逻辑。因此,我想重用它(不是整个 Select 语句,只是名称映射部分)。
我试图编写一个只使用实体的函数:
public static string GetProductName(Product product, int languageID)
{
return product.LanguageKey.LanguageValues.AsQueryable()
.FirstOrDefault(q => q.LanguageID == languageID && q.Active).Value;
}
但是,在调用该方法时,我(显然)收到错误
LINQ to Entities does not recognize the method {X} method, and this method cannot be translated into a store expression
我在 Whosebug 上搜索了很多文章,但大多数都解决了重用整个 Select 表达式的问题。是否可以重复使用它?或者我是否必须创建数据库存储过程或函数?
一种解决方案是使用 LINQKit.
首先,您需要将您的方法修改为return这样的表达式:
public Expression<Func<Product, string>> CreateExpression(int languageID)
{
return product => product.LanguageKey.LanguageValues.AsQueryable()
.FirstOrDefault(q => q.LanguageID == languageID && q.Active).Value;
}
顺便说一下,我不认为你需要在这里调用 .AsQueryable()
。
那么您可以进行以下操作:
var expression = CreateExpression(currentLanguageID);
var model = new ProductListViewModel()
{
Products = products.AsExpandable()
.Select(q => new ProductViewModel()
{
// Other mapping
Name = expression.Invoke(q),
})
.OrderBy(q => q.Name)
};
注意 .AsExpandable()
对 products
变量的调用。
此方法来自 LINQKit,它围绕 IQueryable
(在您的例子中是 products
)创建了一个包装器,以允许使用您的 lambda 表达式中的表达式。
另请注意同样来自 LINQKit 的 Invoke
方法。它允许您在其他表达式中使用 expression
,即 q => new ProductViewModel(...
.
我有以下 Select
表达式将在数据库端执行:
var model = new ProductListViewModel()
{
Products = products
.Select(q => new ProductViewModel()
{
// Other mapping
Name = q.LanguageKey.LanguageValues.FirstOrDefault(p => p.LanguageKeyID == currentLanguageID && p.Active).Value,
})
.OrderBy(q => q.Name)
};
如您所见,名称部分很长,我程序的其他部分也使用相同的逻辑。因此,我想重用它(不是整个 Select 语句,只是名称映射部分)。
我试图编写一个只使用实体的函数:
public static string GetProductName(Product product, int languageID)
{
return product.LanguageKey.LanguageValues.AsQueryable()
.FirstOrDefault(q => q.LanguageID == languageID && q.Active).Value;
}
但是,在调用该方法时,我(显然)收到错误
LINQ to Entities does not recognize the method {X} method, and this method cannot be translated into a store expression
我在 Whosebug 上搜索了很多文章,但大多数都解决了重用整个 Select 表达式的问题。是否可以重复使用它?或者我是否必须创建数据库存储过程或函数?
一种解决方案是使用 LINQKit.
首先,您需要将您的方法修改为return这样的表达式:
public Expression<Func<Product, string>> CreateExpression(int languageID)
{
return product => product.LanguageKey.LanguageValues.AsQueryable()
.FirstOrDefault(q => q.LanguageID == languageID && q.Active).Value;
}
顺便说一下,我不认为你需要在这里调用 .AsQueryable()
。
那么您可以进行以下操作:
var expression = CreateExpression(currentLanguageID);
var model = new ProductListViewModel()
{
Products = products.AsExpandable()
.Select(q => new ProductViewModel()
{
// Other mapping
Name = expression.Invoke(q),
})
.OrderBy(q => q.Name)
};
注意 .AsExpandable()
对 products
变量的调用。
此方法来自 LINQKit,它围绕 IQueryable
(在您的例子中是 products
)创建了一个包装器,以允许使用您的 lambda 表达式中的表达式。
另请注意同样来自 LINQKit 的 Invoke
方法。它允许您在其他表达式中使用 expression
,即 q => new ProductViewModel(...
.