2017-11-02 8 views
0

에서 많은 관계의 결과 목록을 얻으려면 데이터베이스 우선 접근 방식을 사용하여 Entity Framework many-to-many relation이 있습니다.Entity Framework

내 클래스는 다음과 같습니다

class User 
{ 
    public int UserId {get; set;} 

    // every User has zero or more Products : 
    public virtual ICollection<Product> Products {get; set;} 

    ... // other properties 
} 

class Product 
{ 
    public int ProductId {get; set;} 

    // every Product belongs to zero or more Users: 
    public virtual ICollection<User> Users {get; set;} 

    ... // other properties 
} 

class MyDbContext : DbContext 
{ 
    public DbSet<User> Users {get; set;} 
    public DbSet<Product> Products {get; set;} 
} 

나는 목록 lstProductIds에 productIds의 목록을 가지고있다. linq

SQL 인 경우 사용자 목록과 제품 목록을 찾아야합니다.

var str = String.Join(",", lstProductIds); 
str = str.Replace(",", "','"); 

var conn = new SqlConnection(cs); 
conn.Open(); 
var cmd = new SqlCommand("SELECT a.UserId,b.ProductId FROM Users a JOIN Product b on a.UserId = b.UserId WHERE ProductId onId IN ('" + str + "')", conn); 
SqlDataReader rdr = cmd.ExecuteReader(); 

while (rdr.Read()) 
{ 
    UserDetails.Add(new UserProduct { OrganizationId = Convert.ToString(rdr["UserId "]), ProductId= Convert.ToString(rdr["ProductId"]) }); 
} 

conn.Close(); 

그래서 사용자 ID와 ProductId 목록을 얻습니다.

나는 linq에서 비슷한 것을 시도했다. 그러나 이것은 결국 제품 하나당 하나의 userId를 제공하게되었다. 내가 FirstOrDefault() 알고

var UserDetails = db.Products.Where(o => lstProductIds.Contains(o.ProductID.ToString())) 
          .Select(o => new UserProduct 
               { ProductId = o.ID.ToString(), 
               UserId = o.Users.Select(a => a.UserId.ToString()).FirstOrDefault() 
               }) 
          .ToList(); 

이 문제이며, 그것은 단지 제품에 대한 하나의 사용자를 선택하는 것 그러나 나는 그것이 나에게 모든 사용자를 가져 오는 방법을 변경합니까?

+0

예, [SelectMany (https://stackoverflow.com/questions/4283866/different-ways-of-using-selectmany는) –

답변

1

, 당신은 당신이 원하는 보낸 결과를 얻을 수 SelectMany를 사용해야합니다. 이것의 라인에

뭔가 :

UserDetails = db.Products.Where(o => lstProductIds.Contains(o.ProductID.ToString())) 
      .SelectMany(o => o.Users.Select(u => new { o, u })) 
      .Select(s => new UserProduct {ProductId = s.o.ProductId.ToString(), 
       UserId =s.u.UserId.ToString()}).ToList(); 
0

EF에서 조인을 사용할 수 있습니다. 이 시나리오를 이해하면 특정 제품 (lstProductIds) 목록이있는 사용자의 모든 제품을 검색하려고합니다. 코드는 테스트되지 않으며, 당신은 가능성이 내부 및 외부 키를 해결해야합니다,하지만 당신은 아마 뭔가를 찾고 :

db.Users.Join(db.Products.Join(lstProductIds, x => x.ProductId, y => y.ProductId, (x, y) => x), x => x.UserId, y => y.UserId, (x, y) => x).Include(x => x.Products).ToList(); 
+0

사람은 이유를 묻는 경우 나는 불필요한 조인을했는데, 예를 들어 그 변명을 사용합니다 : P – Tebc

3

이 SelectMany (또는 LINQ에 해당)의 일이다. @ 데이비드가 지적 하듯이

예를 들면

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations.Schema; 
using System.Data.Entity; 
using System.Linq; 

namespace Ef6Test 
{ 


    class User 
    { 
     public int UserId { get; set; } 

     // every User has zero or more Products : 
     public virtual ICollection<Product> Products { get; } = new HashSet<Product>(); 


} 

    class Product 
    { 
     public int ProductId { get; set; } 

     // every Product belongs to zero or more Users: 
     public virtual ICollection<User> Users { get; } = new HashSet<User>(); 


    } 

    class Db : DbContext 
    { 
     public DbSet<User> Users { get; set; } 
     public DbSet<Product> Products { get; set; } 
    } 




    class Program 
    { 
     static void Main(string[] args) 
     { 

      Database.SetInitializer(new DropCreateDatabaseAlways<Db>()); 

      using (var db = new Db()) 
      { 

       db.Database.Log = m => Console.WriteLine(m); 
       db.Database.Initialize(true); 

       var lstProductIds = new List<int>() { 1, 2, 3 }; 

       var q = from p in db.Products 
         where lstProductIds.Contains(p.ProductId) 
         from u in p.Users 
         select new { p.ProductId, u.UserId }; 

       var UserDetails = q.ToList(); 
      } 

      Console.WriteLine("Hit any key to exit"); 
      Console.ReadKey(); 
     } 
    } 
}