Как получить присоединение к IQueryable с моделью любого типа sql С#

У меня есть эта модель ExpenseReport

public class ExpenseReport
    {
        public Guid Id { get; set; }
        public Guid InternalId { get; set; }
        public Guid AccountId { get; set; }
        public string Alias { get; set; }
        public bool IsDraft { get; set; }
        public int BaseCurrencyId { get; set; }
        public Guid ContactId { get; set; }
        public Contact Contact { get; set; }
        public Guid? JobId { get; set; }
        public Job Job { get; set; }
        public Customer Customer { get; set; }
        public Guid CustomerId { get; set; }
        public DateTime? PublishedOn { get; set; }
        public DateTime? ExpectedPayDate { get; set; }
        public ExpenseReportStatus Status { get; set; }
        public ExpenseReportStatusEnum StatusId { get; set; }
        public string OriginReference { get; set; }
        public decimal AdvanceValue { get; set; }
        public decimal TotalValue { get; set; }
        public string CreatedBy { get; set; }
        public DateTime CreatedOn { get; set; }
        public string UpdatedBy { get; set; }
        public DateTime UpdatedOn { get; set; }
    }

Мне нужно присоединиться, чтобы получить JOB, CUSTOMER, и Contact с другого стола

когда я использую LINQ для получения этих значений, он возвращает мне null их. Что было бы соединением этого возвращения

Мой запрос

  public IQueryable<ExpenseReport> ExpenseReports => (from exReport in _dataContext.ExpenseReport
                                                            join job in _dataContext.Job on exReport.JobId equals job.Id
                                                            join contact in _dataContext.Contact on exReport.ContactId equals contact.Id
                                                            join customer in _dataContext.Customer on exReport.CustomerId equals customer.Id
                                                            select exReport );

Неясно, какую реализацию IQueryable вы используете. Ответ зависит от того, используете ли вы EntityFramework, Linq2SQL, nHibernate, OData и т. д.

Aron 27.05.2019 03:48

Я использую EntityFramework с SQL-сервером

Eliemerson Fonseca 27.05.2019 03:59

Если вы используете EntityFramework, вам НИКОГДА не следует использовать ключевое слово join. Ваш EDM должен быть настроен таким образом, чтобы ваш класс ExpenseReport имел свойство навигации ExpenseReport.Job, ExpenseReport.Customer и ExpenseReport.Contact. Кроме того, ваш Linq неверен в том, что вы выбираете только ExpenseReport. В терминах SQL вы делаете Select A.* from A join B on....

Aron 27.05.2019 04:23

Что может быть лучше, чтобы принести данные, без того, чтобы я разоблачил то же самое. Нужно ли мне указывать только JOBNAME, нужно ли использовать INCLUDE и использовать только свойство Name?

Eliemerson Fonseca 27.05.2019 04:28

Зависит от того, где вы пишете свой код. Для правильного повторного использования любой библиотечный код должен просто возвращать IQueryable<ExpenseReport>. Только в бизнес-логике потребителя вы должны делать проекцию на ExpenseReport.Job.Name, возможно, с анонимным классом.

Aron 27.05.2019 04:48

настройка выполняется в configEntity. Мое бизнес-правило заключается в том, чтобы приводить только несколько полей работы, таких как имя и идентификатор. Потому что не могу выставить даоды. Я застрял. Я не знаю, правильно ли это .Include(x => x.Job).Select(обязательно)

Eliemerson Fonseca 27.05.2019 04:54

Давайте продолжить обсуждение в чате.

Aron 27.05.2019 05:09

неверно, что вы никогда не должны использовать ключевое слово join. ключевое слово соединения (или метод расширения) — это самый простой способ реализовать внутреннее соединение или объединить столбцы, которые не являются ключами. Однако для наиболее вероятных требуемых левых внешних соединений на FK=PK «ручное» соединение не требуется.

DevilSuichiro 27.05.2019 08:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете просто сделать следующее в своем бизнес-классе

var results = from report in _context.ExpenseReport
              select new { Report = report, JobName = report.Job.Name };
foreach(var x in results)
{
    Console.WriteLine($"Got job {x.JobName} with { x.Report }");
}
Ответ принят как подходящий

Мое решение состояло в том, чтобы создать DTO, который возвращает только то, что мне нужно, и использовать .Include

var ownerData = _repository.ExpenseReports
                .Where(w => w.AccountId.Equals(_identityService.Identity.CurrentAccount.Id))
                .Include(x => x.Customer)
                .Include(x => x.Job)
                .Select(x => new MyExpenseReportDTO
                {
                   Id = x.Id,
                   InternalId = x.InternalId,
                   Alias = x.Alias,
                   Job = x.Job.Name,
                   CreatedOn = x.CreatedOn,
                   ExpectedPayDate = x.ExpectedPayDate,
                   Customer = x.Customer.Name,
                   CostCenterName = x.Job.CostCenter.Name,
                   BaseCurrencyId = x.BaseCurrencyId,
                   Status = x.Status.Name,
                   TotalValue = x.TotalValue
                });

Да, IMO с использованием DTO в большинстве случаев является лучшим выбором. Обратите внимание, что из-за SelectIncludes теперь избыточны.

Gert Arnold 27.05.2019 22:39

Другие вопросы по теме