Как связать дополнительные свойства частичного класса при выполнении запроса SQL в рамках сущности? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть SQL-запрос с динамическими предложениями where:

 string qry= "select p.*,u.fname as username from Proforma p inner join users u on u.userid=p.userid where " + where1 + " and " + where2 + " and " + where3 + " order by p.userid,invoicedate desc";

Я добавил дополнительное свойство, используя это

namespace root.Models.db
{
    public partial class Proforma
    {
       public string username { get; set; }
    }
}

Теперь я пытаюсь получить данные сразу, используя это:

List<Proforma> pm = db.Database.SqlQuery<Proforma>(qry).ToList();

Я ожидал, что он получит имя пользователя из базы данных и связывается соответственно.Но это не работает.

Пожалуйста, помогите.Заранее спасибо.

1 Ответ

0 голосов
/ 13 сентября 2018

Чтобы уточнить настройку User и Performa.

Если отношение равно 1: 1 для обеих таблиц с общим идентификатором пользователя:

public class User 
{
  public int UserId {get; set;}
   // .. other User fields.

  public virtual Performa Performa {get; set;}
}

public class Performa
{
  public int UserId {get; set;}
  // .. other Performa fields.

  public virtual User User {get; set;}
}

public class UserConfiguration : EntityTypeConfiguration<User>
{
  public UserConfiguration()
  {
    ToTable("Users");
    HasKey(x => x.UserId)
      .Property(x => x.UserId)
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

    HasRequired(x => x.Performa)
      .WithRequiredPrincipal(x => x.User);
  }
}

public class PerformaConfiguration : EntityTypeConfiguration<Performa>
{
  public PerformaConfiguration()
  {
    ToTable("Performas");
    HasKey(x => x.UserId)
      .Property(x => x.UserId)
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
  }
}

Оттуда я бы настоятельно рекомендовал использовать объекты ViewModels / DTO для возврата к вызывающим представлениям / коду, а не для передачи назад сущностей. Это позволяет избежать всевозможных проблем с производительностью из-за отложенной загрузки и уменьшает объем данных, проходящих по проводам от БД к клиенту.

var performaQuery = db.Database.SqlQuery<Proforma>(qry);
var viewModels = performaQuery.Select(x => new PerformaViewModel 
{
  UserId = x.UserId,
  PerformaName = x.Name,
  UserName = x.User.Name
}).ToList();

Используя этот подход, вы, вероятно, можете уменьшить или исключить необходимость динамических запросов. Если ваши сущности сопоставлены со связями и вы хотите загрузить Performa, скажем, UserName вместо PerformaName или InvoiceDate ...

public IEnumerable<PerformaViewModel> LoadByCriteria(string userName = null, string performaName = null, DateTime? invoiceDate = null)
{
   var query = context.Performas.Where(x => x.IsActive); // Global filter example...
   if (!string.IsNullOrEmpty(userName))
     query = query.Where(x => x.User.UserName == userName);
   if (!string.IsNullOrEmpty(performaName))
     query = query.Where(x => x.PerformaName == performaName);
   if (invoiceDate.HasValue)
     query = query.Where(x => x.InvoiceDate == invoiceDate);

  var viewModels = query.Select(x => new PerformaViewModel 
  {
    UserId = x.UserId,
    PerformaName = x.Name,
    UserName = x.User.Name
  }).ToList();

  return viewModels;
}

Это просто базовый пример для составления выражений Linq. Вам нужно будет уточнить область контекста, независимо от того, используется ли единица работы или контекст БД, ограниченный запросом и предоставленный контейнером IoC, или объявленный с помощью блока using(). EF выполнит это с условным предложением WHERE с применимыми условиями AND, если необходимо, и вернет только выбранные поля.

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