【发布时间】:2017-11-30 19:04:56
【问题描述】:
我不确定我是否正确地提出了这个问题,或者以一种可以理解的方式,但它是这样的:
我正在尝试找出一种动态方法来在数据库上下文的选择中设置值。我在整个代码中的一百多个地方都使用了我称之为 CodeTableValuePOCO 的东西,而且我不想在每次需要时都指定整个表达式(尤其是查找 CodeName 值的语法)。因此,我尝试使用这样的表达式来动态生成它。
internal static Expression<Func<CodeTableValue, CodeTableValuePOCO>> GetCodeTableValueSelectorExpression(int languageId) {
return x => new CodeTableValuePOCO
{
Code = x.Code,
// Check if there are any translations for the code name
CodeName = x.Translations != null
// If there are, check if there is a translation for user's language
? x.Translations.LanguageTranslationTexts.Count(t => t.Language_ID == languageId) > 0
// If there is a translation, take the first for the given language
? x.Translations.LanguageTranslationTexts.FirstOrDefault(t => t.Language_ID == languageId).Text
// Else, default to codeName
: x.CodeName
// Else, default to codeName
: x.CodeName,
CodeTableId = x.CodeTable.CodeTableID,
Id = x.CodeTableValueID,
Key = x.CodeTable.Key,
ParentId = x.ParentID
};
}
但是,我不知道如何在我的代码中使用上述表达式。我认为如果我只是在寻找 CodeTableValuePOCO 就可以了
,但 CodeTableValuePOCO 嵌入在较大的选择中,如下例所示。显然,它不起作用,因为程序需要一个 CodeTableValuePOCO,但得到一个表达式。
using (MyDbContext db = new MyDbContext()) {
return db.Notifications
.Where(x => x.id == 1)
.Select(x => new NotificationPOCO
{
Id = x.Id,
Message = x.Message,
//This part is, obviously, not working
Type = code.GetCodeTableValueSelectorExpression(2)
})
.ToList();
}
}
【问题讨论】:
-
真的是
code.GetCodeTableValueSelectorExpression(2)- 即它不依赖于您选择的每一行吗?如果是这样,它可以很容易地作为预先计算的值取出(是的,它可能意味着两次往返 DB 调用,但在您看到这导致实际的性能问题之前,我不会太担心它)。另一方面,如果GetCodeTableValueSelectorExpression( )是一个必须为每条被选中的记录执行的内部查询,那么您可以通过几种不同复杂度的方法来处理它,包括手动构建表达式树。 -
顺便说一句,假设你的意思是后者,你有没有试过只做
x.CodeTables.Select( GetCodeTableValueSelectorExpression(2) )看看有没有用? -
谢谢,但是不,它是一个单独的 codeTableValue,不是一个集合,但是,可以有数千个父项,所以我不能让它成为两个单独的查询。
-
我还是有点困惑 - 正如所写,
GetCodeTableValueSelectorExpression()返回一个接受CodeTableValue的函数的表达式,但在您的示例中,您实际上并没有尝试调用返回 - 假设您是,CodeTableValue 参数来自哪里?如果父查询中的每一行没有不同的东西,那么它肯定可以被取出。
标签: c# entity-framework lambda linq-to-sql expression-trees