Возврат данных EF Core в методе
Наверно я изобретаю велосипед с квадратными колесами(возможно есть более элегантное решение).Мне нужно, что бы метод возвращал список всех объектов которые были объеденены по нескольким таблицам:
public List<Address> GetAddress()
{
using (var db = new CrmDbContext())
{
var address = from a in db.Addresses
join City in db.Cities on a.CityId equals City.CityId
join Area in db.Areas on a.AreaId equals Area.AreaId
select a;
List<Address> result = address.ToList();
return result;
}
}
Если я вывожу так:
foreach(var address in addressModel.GetAddress())
{
WriteLine(address.City.CityName);
}
То у меня вылетает Ecxeption
System.NullReferenceException: "Object reference not set to an instance of an object."
Скорей всего я зря так делаю. Но хотелось бы хранить метод по выводу объектов(например адрессов) в отдельном классе и выводить через метод.
Ответы (2 шт):
Почему вы не хотите использовать методы Linq? Для примера, представим, что у вас есть таблица UserEntity:
public int Id { get; set; }
public string Login { get; set; }
И таблица телефонов PhoneEntity:
public int Id { get; set; }
public string Phone { get; set; }
Объединим это всё связью один-ко-многим. UserEntity:
public int Id { get; set; }
public string Login { get; set; }
public ICollection<PhoneEntity> Phones { get; set; }
И сам телефон PhoneEntity:
public int Id { get; set; }
public string Phone { get; set; }
public int UserId { get; set; }
public UserEntity User { get; set; }
Как теперь это всё вытянуть и привязать к UserEntity все его телефоны PhoneEntity:
var users = _dbContext.Users.Include(user => user.Phones).ToList();
Тут мы используем .Include(), который аналогичный использованию LEFT JOIN
Далее представим, что у вас к телефону ещё привязана книга контактов (PhoneEntity -> ContactEntity как one-to-many), тогда запрос, который объеденит это всё будет выглядеть вот так:
var users = _dbContext.Users
.Include(user => user.Phones)
.ThenInclude(phone => phone.Contacts)
.ToList();
Далее для примера, мы можем изменить нашего UserEntity сделующим образом:
public int Id { get; set; }
public string Login { get; set; }
public ICollection<PhoneEntity> Phones { get; set; }
public ICollection<DocumentEntity> Documents { get; set; }
Как нам вытянуть все данные вместе? Вот так:
var users = _dbContext.Users
.Include(user => user.Phones)
.ThenInclude(phone => phone.Contacts)
.Include(user => user.Documents)
.ToList();
Далее всё по аналогии. Это замечательная аналогия тому, что вы хотите.
P.S.: Я не писал прямой ответ на ваш вопрос, а лишь предоставил информацию для того, что бы вы разобрались с этими понятиями и смоги самостоятельно выучить этот материал и решить задачу
UPD: если вы хотите сделать выборку, используйте метод .Where(), вот пример использования для последнего примера кода:
var users = _dbContext.Users
.Where(user => user.Id > 100)
.Include(user => user.Phones)
.ThenInclude(phone => phone.Contacts)
.Where(phone => phone.Phone != "1234567890")
.Include(user => user.Documents)
.ToList();
Linq по умолчанию делает "ленивую" выборку, не включая в результат значения из связанных таблиц. Нужно прямо указать, какие поля выборки, указывающие на другие таблицы, вы хотите загрузить, с помощью метода Include. Например, как это приведено в другом ответе через "объектный" стиль и "дот-нотацию".
Но, насколько я понял из ответа на английском СО, Include можно использовать и с вашим sql-стилем запросов. Так должно сработать:
var address = (from a in db.Addresses
join City in db.Cities on a.CityId equals City.CityId
join Area in db.Areas on a.AreaId equals Area.AreaId
select a).Include("City");
^^^^^^^^^^^^^^^^ загружаем в поле связанные значения