Соединение C# linq, возвращающее несколько результатов

#c# #linq

Вопрос:

У меня есть этот запрос, модель может иметь несколько B и C. Модель имеет 2 Cs, что приводит к возвращению 2 моделей. Предполагается, что он вернет только 1 модель с 1 A и списком B и C, возможно ли это сделать в linq?

Таблица моделей имеет идентификатор модели, имя

Таблица B содержит ставку, идентификатор модели, имя

Таблица C содержит CId, идентификатор модели, имя

 var x = 
    (from model in this.GetDefaultQuery()
    join a in _context.a on model.modelId equals a.modelId
    join b in _context.b on model.modelId equals b.modelId //this should be a list of b
    join c in _context.c on model.modelId equals c.modelId //this should be a distinc list of c
    select new
    {
        M = model,
        A = A,
        B = B, //this should be a list of B's Name
        C = C, //this should be a distinc list of C's Name
    })
    .Where(x => x.model.modelId == modelId);
 

Комментарии:

1. У вас есть свойства навигации, связанные с этими идентификаторами? Если это так, вы можете использовать их вместо присоединения.

Ответ №1:

Почему вам нужно ПРИСОЕДИНИТЬСЯ, должно быть первым вопросом. При правильных отношениях вам это даже не нужно (и не должно).

То, что вы описываете, похоже на то, что:

 var result = 
    (from model in this.GetDefaultQuery()
    select new
    {
        A = (from a in _context.a where model.aId == a.aId select a).ToList(),
        B = (from b in _context.b where model.bId == b.bId select b).ToList(),
        C = (from c in _context.c where model.cId == c.cId select c).Distinct().ToList()
    })
    .Where(x => x.modelId == modelId);
 

ПРАВКА: Было трудно писать в синтаксисе понимания. В синтаксисе метода это проще:

 var result = this.GetDefaultQuery()
      .Where(x => x.modelId == modelId)
      .Select(model => new {
          A = _context.a.Where(x => x.aId == model.aId).ToList(),
          B = _context.b.Where(x => x.bId == model.bId).Distinct().ToList(),
          C = _context.c.Where(x => x.cId == model.cId).ToList()
});
 

PS: Сгенерированный SQL, скорее всего, будет очень неэффективным.

ИЗМЕНИТЬ: Рабочий образец. Обратите внимание, что у меня есть строка подключения, а также ваша модель на самом деле не имеет свойств навигации, как вы предлагали, здесь у меня есть свойства навигации, но они не используются для имитации вашего случая. В противном случае эти клиенты ctx.Где(…) будет просто o.Клиент в качестве примера.

 string defaultConString = @"server=.SQLExpress2012;Database=Northwind;Trusted_Connection=yes;";

void Main()
{
    var ctx = new MyContext(defaultConString);

    var result = ctx.Orders
        .Where(o => o.OrderId == 10249)
        .Select(o => new
        {
            A = ctx.Customers.Where(c => c.CustomerId == o.CustomerId).ToList(), // Single in fact. Could be SingleOrDefault()
            B = ctx.Employees.Where(e => e.EmployeeId == o.EmployeeId).ToList(),
            C = ctx.OrderDetails.Where(od => od.OrderId == o.OrderId).ToList()

        }

        );

    // Check result - Linqpad sample
    //result.Dump(); 
}


public class MyContext : DbContext
{
    public MyContext(string connectionString)
       : base(connectionString)
    { }
    public DbSet<Customer> Customers { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetail> OrderDetails { get; set; }
    public DbSet<Product> Products { get; set; }
    public DbSet<Employee> Employees { get; set; }
}



public class Customer
{
    [Key]
    public string CustomerId { get; set; }
    public string CompanyName { get; set; }
    public string ContactName { get; set; }
    // ...
    //public virtual List<Order> Orders { get; set; }
}

public class Order
{
    [Key]
    public int OrderId { get; set; }
    public string CustomerId { get; set; }
    public int EmployeeId { get; set; }
    public DateTime OrderDate { get; set; }
    public DateTime? ShippedDate { get; set; }
    [ForeignKey("CustomerId")]
    public Customer Customer { get; set; }
    [ForeignKey("EmployeeId")]
    public Employee Employee { get; set; }
    public virtual List<OrderDetail> OrderDetails { get; set; }
}

[Table("Order Details")]
public class OrderDetail
{
    [Key]
    [Column(Order = 1)]
    public int OrderId { get; set; }
    [Key]
    [Column(Order = 2)]
    public int ProductId { get; set; }
    public decimal UnitPrice { get; set; }
    public Int16 Quantity { get; set; }
    [ForeignKey("ProductId")]
    public Product Product { get; set; }
    [ForeignKey("OrderId")]
    public Order Order { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    // ...
}

public class Employee
{
    [Key]
    public int EmployeeId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
 

Комментарии:

1. Привет, спасибо за ваш вклад, я попробую это, также обновил вопросы об идентификаторах.

2. я получаю ошибку «множественная реализация dbset шаблона запроса<> неоднозначный вызов куда».

3. @user10860402, Вы не предоставили образцы данных и свою модель.

4. B и C оба имеют свойство идентификатора модели. модель может иметь много B и C. B и C могут иметь только 1 модель. также обновлен вопрос извините за ошибку перед

5. @user10860402, пожалуйста, предоставьте образец и модель.