首页 > 解决方案 > 带有期望的 Linq:在此上下文中仅支持原始类型或枚举类型

问题描述

我有这个异常:无法创建类型为 ....ViewModels.Yarn.FilterNameDto' 的常量值。此上下文仅支持原始类型或枚举类型。

视图模型:

public class YarnListViewModel
{
    public YarnListFilter YarnListFilter { get; set; }
    public IEnumerable<FilterNameDto> FilterNames { get; set; }
}

public class YarnListFilter
{
    public int? BrandId { get; set; }
    public string ProductName { get; set; }
}

public class FilterNameDto
{
    public string ProductName { get; set; }
}

在控制器中:

List<FilterNameDto> nlnames = new List<FilterNameDto>
{
    new FilterNameDto { ProductName = "Farouche" },
    new FilterNameDto { ProductName = "La Parisienne" },
...
};

var filternamesdb = _context.YarnFullAdmins
                    .Where(n => n.ProductName != null)
                    .GroupBy(n => n.ProductName)
                    .Select(n => n.FirstOrDefault());
if (yarnListFilter.BrandId > 0)
    filternamesdb = filternamesdb.Where(b => b.BrandId == yarnListFilter.BrandId);

// Until here everything works fine

var filternamesdblist = filternamesdb.Select(n => new FilterNameDto
    {
        ProductName = n.ProductName,
    }).Except(nlnames).ToList(); // I remove the names who are in the nlnames list

nlnames.AddRange(filternamesdblist); // And I add them so they come out first

var filternames = filternamesdblist;
if (yarnListFilter.BrandId == null || yarnListFilter.BrandId == 1)
    filternames = nlnames;

var viewModel = new YarnListViewModel
{
FilterNames = filternames
};

    return View(viewModel);

.Exept 是我的问题!

看法:

@Html.DropDownListFor(f => f.YarnListFilter.ProductName
, new SelectList(Model.FilterNames, "ProductName", "ProductName")
,"Filter by Name"
, new { @class = "form-control", @onchange = "this.form.submit();" })

我的目标是让实际上在查询结果中的一些项目(在 nlnames 列表中引用)(在此列表中的任何地方)首先出现。所以,我想我将它们从列表中删除,然后添加它们,以便它们首先被列出。还是有(我敢肯定有)更好的方法来实现这一目标?!?!?

简而言之:数据库返回 Aaa、Bbb、Ccc、Ddd、Eee 而我希望 Bbb、Ddd 成为第一个!在此先感谢您的帮助。

标签: c#linqmodel-view-controller

解决方案


问题是您的对象nlnames无法转换为 SQL Server 可以理解的内容。为了解决这个问题,您可以.ToList().Except()

var filternamesdblist = filternamesdb
    .Select(n => new FilterNameDto
    {
        ProductName = n.ProductName,
    })
    .ToList()
    .Where(n => !nlnames.Any(nl => nl.ProductName == n.ProductName))
    .ToList();

或者,您可以更改 SQL Server 可以理解的nlnames类型List<string>

var nlnames = new List<string> { "Farouche", "La Parisienne" };

var filternamesdblist = filternamesdb
    .Where(n => !nlnames.Contains(n.ProductName))
    .Select(n => new FilterNameDto
    {
        ProductName = n.ProductName,
    })
    .ToList();

推荐阅读