20

LINQtoEntityの左外部結合を理解しようとしています。たとえば、次の3つのテーブルがあります。

Company、CompanyProduct、Product

CompanyProductは、CompanyとProductの2つの親テーブルにリンクされています。

特定の製品にCompanyProductが存在するかどうかに関係なく、すべてのCompanyレコードと関連するCompanyProductを返したいです。Transact SQLでは、次のように左外部結合を使用してCompanyテーブルから移動します。

SELECT * FROM Company AS C
LEFT OUTER JOIN  CompanyProduct AS CP ON C.CompanyID=CP.CompanyID
LEFT OUTER JOIN  Product AS P ON CP.ProductID=P.ProductID 
WHERE      P.ProductID = 14 OR P.ProductID IS NULL

私のデータベースには3つの会社があり、2つのCompanyProductレコードが14のProductIDに関連付けられています。したがって、SQLクエリの結果は予想される3つの行であり、そのうち2つはCompanyProductとProductに接続され、1つはCompanyテーブルとnullを持っています。 CompanyProductテーブルとProductテーブルにあります。

では、同様の結果を達成するために、LINQ toEntityで同じ種類の結合をどのように記述しますか?

いくつかの異なることを試しましたが、構文を正しく取得できません。

ありがとう。

4

7 に答える 7

16

解決しました!

最終出力:

theCompany.id: 1  
theProduct.id: 14  
theCompany.id: 2  
theProduct.id: 14  
theCompany.id: 3  

これがシナリオです

1-データベース

--Company Table
CREATE TABLE [theCompany](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [value] [nvarchar](50) NULL,
 CONSTRAINT [PK_theCompany] PRIMARY KEY CLUSTERED 
( [id] ASC ) WITH (
    PAD_INDEX  = OFF, 
    STATISTICS_NORECOMPUTE  = OFF, 
    IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS  = ON, 
    ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY];
GO


--Products Table
CREATE TABLE [theProduct](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [value] [nvarchar](50) NULL,
 CONSTRAINT [PK_theProduct] PRIMARY KEY CLUSTERED 
( [id] ASC
) WITH (    
    PAD_INDEX  = OFF, 
    STATISTICS_NORECOMPUTE  = OFF, 
    IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS  = ON, 
    ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY];
GO


--CompanyProduct Table
CREATE TABLE [dbo].[CompanyProduct](
    [fk_company] [int] NOT NULL,
    [fk_product] [int] NOT NULL
) ON [PRIMARY];    
GO

ALTER TABLE [CompanyProduct]  WITH CHECK ADD CONSTRAINT
    [FK_CompanyProduct_theCompany] FOREIGN KEY([fk_company]) 
    REFERENCES [theCompany] ([id]);
GO

ALTER TABLE [dbo].[CompanyProduct] CHECK CONSTRAINT 
    [FK_CompanyProduct_theCompany];
GO

ALTER TABLE [CompanyProduct]  WITH CHECK ADD CONSTRAINT 
    [FK_CompanyProduct_theProduct] FOREIGN KEY([fk_product]) 
 REFERENCES [dbo].[theProduct] ([id]);
GO

ALTER TABLE [dbo].[CompanyProduct] CHECK CONSTRAINT 
    [FK_CompanyProduct_theProduct];

2-データ

SELECT [id] ,[value] FROM theCompany
id          value
----------- --------------------------------------------------
1           company1
2           company2
3           company3

SELECT [id] ,[value]  FROM theProduct
id          value
----------- --------------------------------------------------
14          Product 1


SELECT [fk_company],[fk_product] FROM CompanyProduct;
fk_company  fk_product
----------- -----------
1           14
2           14

3-VS.NET2008のエンティティ

代替テキストhttp://i478.photobucket.com/albums/rr148/KyleLanser/companyproduct.png
エンティティコンテナ名は「testEntities」です(モデルのプロパティウィンドウに表示されます)

4-コード(ついに!)

testEntities entity = new testEntities();

var theResultSet = from c in entity.theCompany
select new { company_id = c.id, product_id = c.theProduct.Select(e=>e) };

foreach(var oneCompany in theResultSet)
{
   Debug.WriteLine("theCompany.id: " + oneCompany.company_id);
    foreach(var allProducts in oneCompany.product_id)
    {
        Debug.WriteLine("theProduct.id: " + allProducts.id);
    }
}

5-最終出力

theCompany.id: 1  
theProduct.id: 14  
theCompany.id: 2  
theProduct.id: 14  
theCompany.id: 3  
于 2008-10-06T18:39:27.007 に答える
6

ITはこのようなものでなければなりません....

var query = from t1 in db.table1
    join t2 in db.table2
    on t1.Field1 equals t2.field1 into T1andT2
    from t2Join in T1andT2.DefaultIfEmpty()


    join t3 in db.table3
    on t2Join.Field2 equals t3.Field3 into T2andT3
    from t3Join in T2andT3.DefaultIfEmpty()
    where t1.someField = "Some value" 
    select 
    {
        t2Join.FieldXXX
        t3Join.FieldYYY


    };

これが私がした方法です....

于 2011-03-18T12:05:15.020 に答える
5

Entity Framework を使用して、Company から Product への多対多のマッピングを設定します。これは CompanyProduct テーブルを使用しますが、エンティティ モデルに CompanyProduct エンティティを設定する必要がなくなります。これが完了すると、クエリは非常に単純になり、個人の好みやデータをどのように表現するかによって異なります。たとえば、特定の製品を販売しているすべての企業が必要な場合は、次のように言えます。

var query = from p in Database.ProductSet
            where p.ProductId == 14
            from c in p.Companies
            select c;

また

var query = Database.CompanySet
            .Where(c => c.Products.Any(p => p.ProductId == 14));

SQL クエリは、製品情報と会社を返します。それが目的の場合は、次のことを試してください。

var query = from p in Database.ProductSet
            where p.ProductId == 14
            select new
            {
                Product = p,
                Companies = p.Companies
            };

別の回答を作成するのではなく、より多くの情報を提供したい場合は、[コメントを追加] ボタンを使用してください。

于 2009-10-02T20:30:47.640 に答える
2

LEFT OUTER JOIN は、Entity Framework で GroupJoin を使用して実行されます。

http://msdn.microsoft.com/en-us/library/bb896266.aspx

于 2010-10-29T18:18:57.567 に答える
1

通常のグループ結合は、左外部結合を表します。これを試して:

var list = from a in _datasource.table1
           join b in _datasource.table2
           on a.id equals b.table1.id
           into ab
           where ab.Count()==0
           select new { table1 = a, 
                        table2Count = ab.Count() };

table1この例では、 への参照がないすべてのレコードが表示されtable2ます。文を省略すると、 のwhereすべてのレコードが取得されますtable1

于 2010-08-20T09:29:06.440 に答える
0

次のようなことを試してください:

from s in db.Employees
join e in db.Employees on s.ReportsTo equals e.EmployeeId
join er in EmployeeRoles on s.EmployeeId equals er.EmployeeId
join r in Roles on er.RoleId equals r.RoleId
where e.EmployeeId == employeeId &&
er.Status == (int)DocumentStatus.Draft
select s;

乾杯!

于 2008-09-17T00:43:38.847 に答える
0

これはどうですか (Entity Designer で Company と Product の間に多対多の関係がありますよね?):

from s in db.Employees
where s.Product == null || s.Product.ProductID == 14
select s;

Entity Framework は、使用する結合の種類を把握できる必要があります。

于 2008-10-06T18:08:37.693 に答える