Join Linq到具有多个左外部联接的实体
我试图理解LINQ到实体中的左外连接。例如,我有以下3个表: 公司,公司产品,产品 CompanyProduct链接到它的两个父表Company和Product 我想返回所有公司记录和关联的CompanyProduct,无论给定产品的CompanyProduct是否存在。在Transact-SQL中,我将使用左外部联接从Company表开始,如下所示:Join Linq到具有多个左外部联接的实体,join,linq-to-entities,outer-join,Join,Linq To Entities,Outer Join,我试图理解LINQ到实体中的左外连接。例如,我有以下3个表: 公司,公司产品,产品 CompanyProduct链接到它的两个父表Company和Product 我想返回所有公司记录和关联的CompanyProduct,无论给定产品的CompanyProduct是否存在。在Transact-SQL中,我将使用左外部联接从Company表开始,如下所示: SELECT * FROM Company AS C LEFT OUTER JOIN CompanyProduct AS CP ON C.Co
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个公司产品记录与ProductID 14关联。因此,SQL查询的结果是预期的3行,其中2行连接到CompanyProduct和Product,1行在CompanyProduct和Product表中仅包含Company表和null
那么,如何在LINQ to实体中编写相同类型的连接以获得类似的结果呢
我尝试了一些不同的方法,但语法不正确
谢谢。请尝试以下内容:
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;
干杯 这个呢(在实体设计器中,公司和产品之间确实存在多对多关系,不是吗?)
实体框架应该能够确定要使用的连接类型。解决了它
最终输出:
theCompany.id: 1
theProduct.id: 14
theCompany.id: 2
theProduct.id: 14
theCompany.id: 3
以下是场景 1-数据库
——公司表
创建表[公司](
[id][int]标识(1,1)不为空,
[value][nvarchar](50)空,
约束[PK_the company]主键群集
([id]ASC)带有(
PAD_索引=关闭,
统计信息\u NORECOMPUTE=OFF,
忽略重复键=关闭,
允许\u行\u锁=打开,
在[主]上允许页面锁定
)关于[初级];
去
--产品表
创建表[产品](
[id][int]标识(1,1)不为空,
[value][nvarchar](50)空,
约束[PK_theProduct]主键群集
([id]ASC
)与(
PAD_索引=关闭,
统计信息\u NORECOMPUTE=OFF,
忽略重复键=关闭,
允许\u行\u锁=打开,
在[主]上允许页面锁定
)关于[初级];
去
--公司产品表
创建表[dbo]。[CompanyProduct](
[fk_company][int]不为空,
[fk_product][int]不为空
)关于[初级];
去
使用CHECK ADD约束更改表[CompanyProduct]
[FK_公司产品公司]外键([FK_公司])
参考文献[公司]([id]);
去
ALTER TABLE[dbo].[CompanyProduct]检查约束
[FK_Company Product_the Company];
去
使用CHECK ADD约束更改表[CompanyProduct]
[FK_公司产品产品]外键([FK_产品])
参考文献[dbo]。[theProduct]([id]);
去
ALTER TABLE[dbo].[CompanyProduct]检查约束
[FK_公司产品];
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.NET 2008中的实体
实体容器名称为“testEntities”(如模型属性窗口中所示) 4-代码(最后!)
testEntities entity=newtestentities();
var theResultSet=来自entity.theCompany中的c
选择新的{company_id=c.id,product_id=c.theProduct.select(e=>e)};
foreach(结果集中的一家公司)
{
Debug.WriteLine(“company.id:+oneCompany.company\u id”);
foreach(var一家公司的所有产品。产品id)
{
Debug.WriteLine(“theProduct.id:+allProducts.id”);
}
}
5-最终输出
theCompany.id: 1
theProduct.id: 14
theCompany.id: 2
theProduct.id: 14
theCompany.id: 3
您需要使用实体框架来设置从公司到产品的多对多映射。这将使用CompanyProduct表,但不需要在实体模型中设置CompanyProduct实体。完成后,查询将非常简单,它将取决于个人偏好以及您希望如何表示数据。例如,如果您只想让所有拥有给定产品的公司,您可以说:
var query = from p in Database.ProductSet
where p.ProductId == 14
from c in p.Companies
select c;
或
SQL查询将返回产品信息以及公司信息。如果这就是你想要的,你可以尝试:
var query = from p in Database.ProductSet
where p.ProductId == 14
select new
{
Product = p,
Companies = p.Companies
};
如果您想提供更多信息,而不是创建另一个答案,请使用“添加注释”按钮。正常组联接表示左外联接。试试这个:
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
语句,您将获得表1的所有记录左侧外部联接通过使用实体框架中的GroupJoin完成:
应该是这样的
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
};
我就是这样做的……。选择(e=>e)
是一个不可操作的选项,可以删除。当然,如果你只使用ID,为什么不说。选择(e=>e.ID)
?@国王:我不同意。OP问:“那么,如何在LINQ to Entity中编写相同类型的联接以获得类似的结果呢?”在LINQ to Entity中这样做的正确方法是建立多对多关系,并通过关系属性访问相关实体。您可以看到OP的最终解决方案使用了相同的策略。我没能解决问题的哪一方面?他也找到了解决办法。解决方案就在这个由米奇提供的链接中below@theKing:我不同意。在使用实体框架时,“组联接”是一种变通方法,当您无法设置上下文以正确建模数据的关系时,可以使用它。在不必要时使用它会产生过多且容易出错的代码。OP找到了“正确的方法”,而不是解决问题。我想我们需要学会不同意。我想知道为什么微软和所有你能在亚马逊上找到的LINQ书籍都推荐使用GroupJoin?我想他们一定已经适应了这种变通办法too@theKing:“LINQ书籍”并不是关于实体框架的。Microsoft和所有LINQ to Entities书籍和文章都推荐多对多映射。这就是为什么他们做了这么大的一个d
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() };
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
};