#c# #linq
#c# #linq
Вопрос:
Я долгое время писал запросы на C # и LINQ. Я хочу просмотреть временный список, ища совпадающие значения в 1 поле (с именем Model). В спецификации говорится, что если есть соответствующая модель, то ее нельзя добавлять в список. Итак, я удаляю повторяющиеся модели и добавляю только уникальные в список, который возвращается. Вот функция, которую я написал для этого:
private List<InstrumentModel> EnsureInstrumentModelListUnique(List<InstrumentModel> instrumentModels)
{
var tmpList = new List<InstrumentModel>();
if (instrumentModels == null || instrumentModels.Count <= 1)
{
//nothing to see here folks, move on
return instrumentModels;
}
for (int i = 0; i < instrumentModels.Count; i )
{
if (i == 0)
{
tmpList.Add(instrumentModels[0]);
}
else
{
//get current model
string model = instrumentModels[i].Model;
//check to see if model is somewhere in the list
var rec = tmpList.Where(t => t.Model == model).FirstOrDefault();
//if it isn't there, put it in
if (rec == null)
{
tmpList.Add(rec);
}
}
}
return tmpList;
}
Он проходит for
цикл 3 раза, прежде чем произойдет сбой. Он вылетает при t.Model
in tmpList.Where(t => t.Model == model).FirstOrDefault()
, утверждая, что t
это null .
Я не понимаю, как t
значение null на третьей итерации цикла. Таблица, из которой instrumentModels
происходит from, содержит 5 записей. Все записи имеют что-то в столбце модели.
Вот определение InstrumentModel, в которое для краткости включены только соответствующие столбцы:
[Table("app.InstrumentModel")]
[DebuggerDisplay("ID == {ID}, Model == {Model}, Inactive == {Inactive}")]
public partial class InstrumentModel
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public InstrumentModel()
{
Instruments = new HashSet<Instrument>();
PersonnelCertifications = new HashSet<PersonnelCertification>();
}
[Key]
public long ID { get; set; }
[Required]
[StringLength(30)]
public string Model { get; set; }
}
Я работаю с WPF, .NET Framework 4.5.2, VS 2019
Комментарии:
1.
if (rec == null) { tmpList.Add(rec); }
прокомментировано «если его там нет, вставьте его» . Это не то, что это делает.2. Я бы сказал, что подобные комментарии на самом деле вредны, потому что они могут помешать вам прочитать то, что вы на самом деле написали.
Ответ №1:
Как указал @madreflection, проблема здесь:
//check to see if model is somewhere in the list
var rec = tmpList.Where(t => t.Model == model).FirstOrDefault();
//if it isn't there, put it in
if (rec == null)
{
tmpList.Add(rec);
}
Я полагаю, что в этом случае вы вставляете rec
, когда должны вставлять model
.
Код проще с Any
помощью . Если вы сделаете это таким образом, нет нулевой переменной, в которой можно запутаться.
bool found = tmpList.Any(t => t.Model == model);
if (!found)
{
tmpList.Add(model);
}
Комментарии:
1. Спасибо, Джон Ву и madreflection. Теперь я вижу свою ошибку. Я был слишком близко к нему, поэтому я его не видел. Нужны другие пары глаз, чтобы рассказать мне об этом. Теперь это очевидно. Кроме того, спасибо, что сообщили мне об этой
Any
фразе. Я предполагаю, что это аналогично SQLEXISTS
.