#c# #linq #model-view-controller
#c# #linq #модель-представление-контроллер
Вопрос:
У меня есть это исключение: невозможно создать постоянное значение типа ….ViewModels.Yarn.FilterNameDto’. В этом контексте поддерживаются только примитивные типы или типы перечисления.
ViewModels:
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; }
}
В Contoller:
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);
.Исключение — моя проблема!
Вид:
@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 были первыми! Заранее спасибо за вашу помощь.
Ответ №1:
Проблема в том, что ваш объект 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();
В качестве альтернативы вы можете изменить тип nlnames
List<string>
, который может быть понятен SQL Server:
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();
Комментарии:
1. Спасибо @Adam. Никаких исключений. Но это не удалило имена из списка. Итак, теперь у меня их 2 раза! Есть идеи?
2. Я думаю, что это будет проблемой
.Except()
, возможно, попробуйте заменить его.Where(n => !nlnames.Any(nl => nl.ProductName == n.ProductName))
. Исключение, вероятно, будет ожидать, что объект будет равен, а ваш не будет таким, какfilternamesdb
поступает из базы данных иnlnames
представляет собой жестко запрограммированный список3. Нет, извините. С этим я возвращаюсь к своему исключению
4.
.ToList()
nlnames
Для предотвращения возникновения этого исключения требуется вызов перед использованием5. Вот и все. Вызов . ToList() и затем . Где работает отлично. Большое вам спасибо @Adam. Хорошего дня.