对于使用Value和Text的相同属性的SelectListItem投影的EFCore SqlException

时间:2018-06-15 13:25:52

标签: c# entity-framework entity-framework-core projection

我创建了一个 SelectListHelper ,以便将所有下拉数据保留在一个中心位置。它将我的数据库中的行投影到IEnumerable<SelectListItem>的集合中,这些集合可以被我的视图使用。以下是该课程的一部分:

public class SelectListHelper
{
    private AppDbContext _db;

    public SelectListHelper(AppDbContext db)
    {
        _db = db;
    }

    public IEnumerable<SelectListItem> GetCountries(bool showAll = false)
    {
        return _db.Set<Country>().Where(x => showAll || x.Enabled == true).OrderBy(x => x.Name).Select(x => new SelectListItem { Value = x.Abbreviation, Text = x.Name }).ToList();
    }

    public IEnumerable<SelectListItem> GetGoogleCategories(bool showAll = false)
    {
        return _db.Set<GoogleCategory>().Where(x => showAll || x.Enabled == true).OrderBy(x => x.Name).Select(x => new SelectListItem { Value = x.Name, Text = x.Name }).ToList();
    }
}

GetCountries,为简洁省略了所有其他功能,工作得很好。他们使用投射到Value的{​​{1}}和Text属性上的不同列。

SelectListItemGetGoogleCategories列投放到Name的{​​{1}}和Value属性上。这会产生以下SqlException:

  

发生了'System.Data.SqlClient.SqlException'类型的异常   Microsoft.EntityFrameworkCore.dll但未在用户代码中处理   列名称“值”无效。

当我查看Text函数生成的SQL时,它看起来像我预期的那样:

SelectListItem

但是,GetCountries函数生成的SQL看起来并不像我预期的那样:

SELECT [x].[Abbreviation] AS [Value], [x].[Name] AS [Text]
FROM [Countries] AS [x]
WHERE [x].[Enabled] = 1
ORDER BY [Text]

我在Visual Studio 2017(15.7.3)中使用EfCore 2.1.0。任何想法可能会发生在这里?我可以通过返回一个Name数组并手动构建GetGoogleCategories列表来解决这个问题,但这让我担心我的数据访问层中的其他内容可能无法正常工作。

SELECT [x].[Name] AS [Text]
FROM [GoogleCategories] AS [x]
WHERE [x].Enabled] = 1
ORDER BY [Value]

1 个答案:

答案 0 :(得分:4)

这是由#12180: Invalid column name: orderby uses a column alias that does not exist跟踪的2.1回归错误。

您的特定情况的解决方法是使用带参数的SelectListItem构造函数(2.1中引入的功能):

return _db.Set<GoogleCategory>()
    .Where(x => showAll || x.Enabled == true)
    .OrderBy(x => x.Name)
    .Select(x => new SelectListItem(x.Name, x.Name) })
    .ToList();

但当然问题仍然存在。