Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework EF查询的select语句中的自定义扩展函数_Entity Framework - Fatal编程技术网

Entity framework EF查询的select语句中的自定义扩展函数

Entity framework EF查询的select语句中的自定义扩展函数,entity-framework,Entity Framework,在我们的数据库中,我们有一个如下所示的表,该表已映射到数据库First EF模型中的一个实体: CREATE TABLE Texts( Id integer, Eng nvarchar(max), Nob nvarchar(max), ... ) 此表中的一行可能相当大,因此我们只想获取用户所做语言选择当前需要的列的值 我的想法是有一个扩展函数来为我做这件事,但我没有任何想法,也找不到任何方法来写它(如果可能的话)。我尝试了一些变体,但(显然)它失败了,出现了一个异常,即无法将

在我们的数据库中,我们有一个如下所示的表,该表已映射到数据库First EF模型中的一个实体:

CREATE TABLE Texts(
  Id integer,
  Eng nvarchar(max),
  Nob nvarchar(max),
  ...
)
此表中的一行可能相当大,因此我们只想获取用户所做语言选择当前需要的列的值

我的想法是有一个扩展函数来为我做这件事,但我没有任何想法,也找不到任何方法来写它(如果可能的话)。我尝试了一些变体,但(显然)它失败了,出现了一个异常,即无法将其转换为存储表达式。所以我有点困了

此函数的用法是:

context.Codes.Where(row => row.Id == 234).Select(row => new {
  row.Id,
  Text = Text.GetLocalizedText("Eng") // This should generate an SQL that only retrieves the Eng 
                                      // column of the Text navigation property (which is 
                                      // connected to the Texts table.
});
这将生成与此类似的选择(除了直接使用Text.Eng外,与上面的示例类似):


是否有人知道这是可能的,如果是;怎么写?如果不可能,有没有人对如何在不检索包含所有列的整个文本实体的情况下解决这个问题有任何其他想法?

一个
IQueryable
的扩展方法可以工作,但它并不像您可能希望的那样灵活,因为您需要根据要执行的投影类型进行扩展,并且无法使用匿名结果对象

这个想法基本上是这样的:

您需要一个命名类(而不是匿名类),可以将其投影到:

public class CodeData
{
    public int Id { get; set; }
    public string LocalizedText { get; set; }
}
然后是带有语言参数的扩展方法:

public static class CustomExtensions
{
    public static IQueryable<CodeData> SelectCodeData(
        this IQueryable<Code> query, string language)
    {
        switch (language)
        {
            case "Eng":
                return query.Select(code => new CodeData
                {
                    Id = code.Id,
                    LocalizedText = code.Text.Eng
                });

            case "Nob":
                return query.Select(code => new CodeData
                {
                    Id = code.Id,
                    LocalizedText = code.Text.Nob
                });
            //... more languages
        }

        throw new ArgumentException("Invalid language code.", "language");
    }
}
那么可以这样称呼它:

using CustomExtensions;

// ...

IQueryable<CodeData> codeDataQuery = context.Codes
    .Where(row => row.Id == 234)
    .SelectCodeData("Eng");
使用自定义扩展;
// ...
IQueryable codeDataQuery=context.code
.Where(row=>row.Id==234)
.选择CodeData(“英文”);

是的,这是我正在考虑的备选方案之一。问题是文本表被用于多个位置。通过使用此替代方案,我必须(每当添加新语言时)将语言添加到代码中使用的每个位置(可能有很多位置),因此,管理此解决方案并不需要太多工作:(
using CustomExtensions;

// ...

IQueryable<CodeData> codeDataQuery = context.Codes
    .Where(row => row.Id == 234)
    .SelectCodeData("Eng");