我们有一个 BaseSchema 类,它包含另一个模式的 IEnumerable,该模式包含我们的应用程序使用的每种语言的数据。我们在基本模式中编写了一个辅助方法,它将获取...
我们有一个 BaseSchema
类,其中包含 IEnumerable
另一个模式,该模式包含我们的应用程序使用的每种语言的数据。
我们在基础模式中编写了一个辅助方法,该方法将获取所提供语言的描述模式中的属性,如果未找到任何属性,则获取第一个具有值的属性。
return await Context.Allergies
.Include(allergy => allergy.Descriptions)
.AsNoTracking()
.Select(allergy => new SynchronizableAllergyViewModel
{
Id = allergy.Id.ToString(),
IsCommon = allergy.IsCommon,
Name = allergy.GetTranslatedString(d => d.Name, Language),
})
.ToListAsync();
public string GetTranslatedString(Func<TMultilingualSchema, string> stringParam,
TLanguageSchemaId languageId)
{
return Descriptions
.OrderBy(d => d.LanguageId.Equals(languageId) ? 0 : 1)
.Select(stringParam)
.FirstOrDefault(d => !string.IsNullOrWhiteSpace(d)) ?? string.Empty;
}
我们在 SQL Server 上使用 .NET 6.0 和 EF Core 6.0.16。
使用辅助方法时,我们得到
LINQ 表达式“d => d.Name”无法翻译
但是,我们可以就地复制方法体并获得预期的结果
return await Context.Allergies
.Include(allergy => allergy.Descriptions)
.AsNoTracking()
.Select(allergy => new SynchronizableAllergyViewModel
{
Id = allergy.Id.ToString(),
IsCommon = allergy.IsCommon,
Name = allergy.Descriptions.OrderBy(d => d.LanguageId.Equals(Language) ? 0 : 1)
.Select(d => d.Name)
.FirstOrDefault(d => !string.IsNullOrWhiteSpace(d)) ?? string.Empty
})
.ToListAsync();
我们尝试改变方法以使用表达式并从参数名称构建表达式,但没有成功。
当我们在带有 EF Core 7.0.5 的 .NET 7 上尝试“复制”解决方案时,它给出与方法调用相同的结果。
来实现 LINQKit
先决条件:
LINQKit
激活
builder
.UseSqlServer(connectionString)
.WithExpressionExpanding(); // enabling LINQKit extension
按下列方式修改您的方法:
public class Allergy
{
... // other properties
[Expandable(nameof(GetTranslatedStringImpl))]
public string GetTranslatedString(Func<TMultilingualSchema, string> stringParam,
TLanguageSchemaId languageId)
{
throw new NotImplementedException();
}
private static Expression<Func<Allergy, Func<TMultilingualSchema, string>, TLanguageSchemaId, string>> GetTranslatedStringImpl()
{
return (allergy, stringParam, languageId) => allergy.Descriptions
.OrderBy(d => d.LanguageId.Equals(languageId) ? 0 : 1)
.Select(stringParam)
.FirstOrDefault(d => !string.IsNullOrWhiteSpace(d)) ?? string.Empty
}
}
之后,您可以在 LINQ 查询中使用您的方法。