ГДЕ не найдено в запросе LINQ - PullRequest
0 голосов
/ 06 ноября 2018

Я пытаюсь написать программу, которая берет информацию об автомобиле из файла .csv, а затем добавляет конкретные сведения о каждом автомобиле в объект списка.

У меня проблемы с использованием запроса LINQ, чтобы найти все автомобили в списке с определенным значением make CITROEN.

Это дает мне ошибку:

Не удалось найти реализацию шаблона запроса для типа источника 'CarList'. «Где» не найдено.

Это также говорит об этом на моем foreach:

оператор foreach не может работать с переменными типа '?' так как '?' не содержит общедоступного определения экземпляра для GetEnumerator

Что я делаю не так? Я следил за страницей Microsoft о том, как использовать LINQ, и я не понимаю ошибку.

Это мой класс программы:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinqPractical
{
    class Program
    {
        static CarList carList = new CarList();

        static void Main(string[] args)
        {
            Car car = new Car();

            StreamReader reader = new StreamReader(File.OpenRead(@"F:\\motfailures.csv"));
            string header = reader.ReadLine();

            while (!reader.EndOfStream)
            {
                string line = reader.ReadLine();
                var values = line.Split(',');

                car.Make = values[0];
                car.Model = values[1];
                car.Year = values[2];
                car.Pass = values[3];
                car.Fail = values[4];

                carList.Add(car);

                Console.WriteLine("Added car to list with details:");
                Console.WriteLine("Make: " + values[0]);
                Console.WriteLine("Model: " + values[1]);
                Console.WriteLine("Year: " + values[2]);
                Console.WriteLine("Pass: " + values[3]);
                Console.WriteLine("Fail: " + values[4]);
            }
            Console.ReadKey();

            ShowMake();
        }

        public static void ShowMake()
        {

            var query = from car in carList
                           where car.Make == "CITROEN"
                           select car;

            foreach (Car c in query)
            {
                Console.WriteLine("Make: " + c.Make + " Model: " + c.Model + " Year: " + c.Year);
            }
        }
    }
}

Список классов:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinqPractical
{
    class CarList
    {
        private List<Car> _list = new List<Car>();

        public void Add(Car newCar)
        {
            _list.Add(newCar);
        }
    }
}

и класс автомобиля:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinqPractical
{
    public class Car
    {
        private string _make;
        private string _model;
        private string _year;
        private string _pass;
        private string _fail;

        public string Make
        {
            get
            {
                return _make;
            }
            set
            {
                _make = value;
            }
        }

        public string Model
        {
            get
            {
                return _model;
            }
            set
            {
                _model = value;
            }
        }

        public string Year
        {
            get
            {
                return _year;
            }
            set
            {
                _year = value;
            }
        }

        public string Pass
        {
            get
            {
                return _pass;
            }
            set
            {
                _pass = value;
            }
        }

        public string Fail
        {
            get
            {
                return _fail;
            }
            set
            {
                _fail = value;
            }
        }
    }
}

Ответы [ 5 ]

0 голосов
/ 06 ноября 2018

Ответ в комментариях, но только для того, чтобы предоставить код ...

В большинстве случаев вам не нужны отдельные поля для ваших свойств. Удаление их значительно улучшит читабельность вашего кода:

public class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    // ...
}

Теперь просто используйте универсальный List и удалите ваш класс CarList (вот почему вы получаете ошибки в своем коде):

var carList = new List<Car>();

Вы хотите добавить по одному уходу на строку, поэтому давайте создадим один уход на строку. Я бы предложил использовать более компактный способ написать это (опять же: легче читать):

while (!reader.EndOfStream)
{
    string line = reader.ReadLine();
    var values = line.Split(',');

    carList.Add(new Car {
      Make = values[0],
      Model = values[1]
    });
}
0 голосов
/ 06 ноября 2018

Я исправил ошибки, но теперь, когда я запускаю программу, она не печатает никаких подробностей из foreach. Я проверил данные, введенные в список, и они больше не перезаписываются. Но ничего найти не могу.

0 голосов
/ 06 ноября 2018

Ошибка, которую вы получаете, состоит в том, что ваш класс CarList не реализует IEnumerable. Комментарий Игоря об использовании списка - правильный путь, если вам не нужны особые функции, которые обеспечит создание собственного типа списка. Не переоценивайте решение, если вам это не нужно.

0 голосов
/ 06 ноября 2018

Код, сбивающий с толку / пропускающий ведение при добавлении метода (add), который просто добавляет во внутренний список.

Класс списка ваших автомобилей CarList - это не список автомобилей, это контейнер, содержащий список автомобилей.

Итак, причина, по которой вы получаете ошибку, заключается в том, что вы пытаетесь взаимодействовать с контейнером CarList, который не перечисляется. Вы должны взаимодействовать на List<Car>, что связано с плохим наименованием ... ваш CarList больше похож на CarProviderA, в котором есть список автомобилей.

не будет работать

 var query = from car in carList -- not a list of cars
             where car.Make == "CITROEN"
             select car;

будет работать

 var query = from car in carList.List  -- where List is a public property of _list to the list of cars
             where car.Make == "CITROEN"
             select car;

Также

Car car = new Car(); 

должен быть в цикле while, вы добавляете один и тот же экземпляр несколько раз, который будет таким же, как и в прошлый раз.

Должно выглядеть примерно так

while (!reader.EndOfStream)
{
    Car car = new Car(); 
    string line = reader.ReadLine();
    var values = line.Split(',');

    car.Make = values[0];
    car.Model = values[1];
    car.Year = values[2];
    car.Pass = values[3];
    car.Fail = values[4];

    carList.Add(car);
}
0 голосов
/ 06 ноября 2018

Linq не может работать ни с одним классом. Он может иметь дело только с классами, которые представляют типизированный список путем реализации IEnumerable<T>

Таким образом, вы либо определяете public class CarList : IEnumerable<Car> и сами реализуете интерфейс, либо просто расширяете класс List, как public class CarList : List<Car>, где вам больше не нужно поле класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...