假设我有这两个实体
if(r.next())
{
System.out.println("User Name Does Exist");
}
else
{
System.out.println("User Does Not Exist");
}
我使用此代码选择产品列表。它们中的每一个都将与给定产品显示位置的图像相关联。
public class Product
{
//..
public ICollection<Photo> Photos { get; set; }
= new List<Photo>();
}
public class Photo
{
//..
public PageLocation PageLocation { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
问题是,当产品没有该位置的图像时,则不会选择该产品。
我在左连接中看到的Every examples显示了如何使用2个来源。在我的情况下,我不需要2个来源,因为我在Product和Image之间有一个导航属性。
有没有办法在不使用2个数据源的情况下完成左连接?像这样的东西
var productList = GetAll().Include(p => p.PhotoImages)
.Where(p =>
p.PhotoImages.Any(
i => i.PageLocation == PageLocation.Home_Slider));
感谢您的帮助
答案 0 :(得分:0)
有没有办法在不使用2个数据源的情况下完成左连接?
我认为没有。在您的SQL查询中,您将加入一个新集,而不是与您的产品相关的照片。
我相信你能做的最好的事情就是这样:
var q = from prod in ctx.Products.Include(p => p.Photos)
join img in (
from ph in ctx.Photos where ph.PageLocation == 1 select new { ph.ProductId, PageLocation = (int?)ph.PageLocation }
) on prod.Id equals img.ProductId into pjoin
from pj in pjoin.DefaultIfEmpty()
select new { prod, photo = pj, pj.PageLocation };
foreach (var p in q)
{
Console.WriteLine($"{p.prod.Id} - {p.photo} - {p.PageLocation}");
}
编辑:此查询中只有一个连接,从生成的SQL中可以看出:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent2].[PageLocation] AS [PageLocation],
[Extent2].[ProductId] AS [ProductId]
FROM [dbo].[Product] AS [Extent1]
LEFT OUTER JOIN [dbo].[Photo] AS [Extent2] ON (1 = [Extent2].[PageLocation]) AND ([Extent1].[Id] = [Extent2].[ProductId])
答案 1 :(得分:0)
好吧,如果使用导航属性,EF会生成一个inner join
的SQL语句。
导航属性如何工作
当我们在代码中应用导航属性时,这意味着我们要求EF自动执行两个表之间的连接。
来源: Navigation Property With Code First (Navigation Property In EF)
因此,您可以使用MS docs - Perform left outer joins上已经找到的示例 - 来实现您的查询。您的SQL示例也有两个来源。第一个Products
表和第二个PhotoImages
表或我误解了你的意思。
您的查询方法可以是:
var products = (
from p in _context.Products
join pi in _context.PhotoImages on p.Id equals pi.ProductId
into productsWithImages
from pwi in productsWithImages.Where(pwi => pwi.PageLocation == 1).DefaultIfEmpty()
select new ExtendedProduct
{
p.Id,
p.Name,
photoId = (int?)pwi.Id,
pwi.PageLocation,
pwi.Url
}
)