SelectListItem 投影的 EFCore SqlException 对值和文本使用相同的 属性
EFCore SqlException for SelectListItem projection using same property for Value and Text
我创建了一个 SelectListHelper 来将我所有的下拉数据填充放在一个中心位置。它将我数据库中的行投影到 IEnumerable<SelectListItem>
的集合中,我的视图可以使用这些集合。这是 class:
的一部分
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
以及为简洁起见而省略的所有其他函数都可以正常工作。他们使用不同的列投影到 SelectListItem
.
的 Value
和 Text
属性上
GetGoogleCategories
将 Name
列投影到 SelectListItem
的 Value
和 Text
属性上。这会产生以下 SqlException:
An exception of type 'System.Data.SqlClient.SqlException' occurred in
Microsoft.EntityFrameworkCore.dll but was not handled in user code
Invalid column name 'Value'.
当我查看 GetCountries
函数生成的 SQL 时,它看起来像我预期的那样:
SELECT [x].[Abbreviation] AS [Value], [x].[Name] AS [Text]
FROM [Countries] AS [x]
WHERE [x].[Enabled] = 1
ORDER BY [Text]
然而,GetGoogleCategories
函数生成的 SQL 与我预期的不同:
SELECT [x].[Name] AS [Text]
FROM [GoogleCategories] AS [x]
WHERE [x].Enabled] = 1
ORDER BY [Value]
我在 Visual Studio 2017 (15.7.3) 中使用 EfCore 2.1.0。任何想法可能会发生什么?我可以通过返回名称数组并手动构建 SelectListItems
列表来解决此问题,但这让我担心我的数据访问层中的其他内容可能无法正常工作。
public class GoogleCategory
{
[Key]
public int Id { get; set; }
[Required, StringLength(250)]
public string Name { get; set; }
public bool Enabled { get; set; } = true;
}
public class Country
{
[Key]
public int Id { get; set; }
[Required, StringLength(250)]
public string Name { get; set; }
[Required, StringLength(2)]
public string Abbreviation { get; set; }
public bool Enabled { get; set; } = true;
}
这是 #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();
当然,问题仍然存在。
我创建了一个 SelectListHelper 来将我所有的下拉数据填充放在一个中心位置。它将我数据库中的行投影到 IEnumerable<SelectListItem>
的集合中,我的视图可以使用这些集合。这是 class:
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
以及为简洁起见而省略的所有其他函数都可以正常工作。他们使用不同的列投影到 SelectListItem
.
Value
和 Text
属性上
GetGoogleCategories
将 Name
列投影到 SelectListItem
的 Value
和 Text
属性上。这会产生以下 SqlException:
An exception of type 'System.Data.SqlClient.SqlException' occurred in Microsoft.EntityFrameworkCore.dll but was not handled in user code Invalid column name 'Value'.
当我查看 GetCountries
函数生成的 SQL 时,它看起来像我预期的那样:
SELECT [x].[Abbreviation] AS [Value], [x].[Name] AS [Text]
FROM [Countries] AS [x]
WHERE [x].[Enabled] = 1
ORDER BY [Text]
然而,GetGoogleCategories
函数生成的 SQL 与我预期的不同:
SELECT [x].[Name] AS [Text]
FROM [GoogleCategories] AS [x]
WHERE [x].Enabled] = 1
ORDER BY [Value]
我在 Visual Studio 2017 (15.7.3) 中使用 EfCore 2.1.0。任何想法可能会发生什么?我可以通过返回名称数组并手动构建 SelectListItems
列表来解决此问题,但这让我担心我的数据访问层中的其他内容可能无法正常工作。
public class GoogleCategory
{
[Key]
public int Id { get; set; }
[Required, StringLength(250)]
public string Name { get; set; }
public bool Enabled { get; set; } = true;
}
public class Country
{
[Key]
public int Id { get; set; }
[Required, StringLength(250)]
public string Name { get; set; }
[Required, StringLength(2)]
public string Abbreviation { get; set; }
public bool Enabled { get; set; } = true;
}
这是 #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();
当然,问题仍然存在。