我的查询有问题,请看一下。我的目标是:
Products
与一个Image
。Products
和Values
可以是Image
Values
和null
返回所有Products
Image
我只需要Values
所以它可以得到Values
Ids
和List<int> of Values
连接表关系 - > ProductValues
可以有很多ImageObjects
也Products
可以有很多ProductValues
但可以有一个Products
ImageObjects
来自Image
问题我不知道如何以正确的方式聚合DistinctBy
以返回每个more linq
的Values
列表
PS我也使用更多的linq
Values
回答Product
我知道这不是一个可以回答的地方,但是meaby有人会对我的代码或meaby有任何建议,它可以做得更清楚或更快。我一直想知道如何长时间执行这个查询,但是当我写信给你时,我得到了一个炫目:)
在var q1 = (from p in Products
join pv in ProductValues on p.ProductId equals pv.ProductId into ljpv
from pv in ljpv.DefaultIfEmpty()
select new
{
ProductId = p.ProductId,
Description = p.Description,
Name = p.Name,
Price = p.Price,
Quantity = p.Quantity,
Type = p.Type,
Values = (from v in ValueTypes
where v.ValueId == pv.ValueId
select new {
ValueId = v.ValueId
}).ToList(),
ImageObjects = (from io in ImageObjects
where io.ProductId == p.ProductId && io.IsDefault == true
select new
{
Image = io.Image,
IsDefault = io.IsDefault,
ProductId = io.ProductId
})
.ToList()
})
.DistinctBy(x=>x.Name)
.OrderBy(x=>x.Name);
q1.Dump();
回答之后 - 代码更快!
Values = (from tmp in ljpv select new { ValueId = tmp.ValueId}),
所以你有一个@Harald Coppoolse
表和一对多关系的 return context.Product.GroupJoin(
context.ProductValue,
context.ImageObject.Include(x => x.Image),
p => p.ProductId,
pv => pv.ProductId,
io => io.ProductId,
(p, pv, io) => new ProductModel
{
ProductId = p.ProductId,
Name = p.Name,
Price = p.Price,
ProductValue = pv
.Select(npv => new ProductValueModel
{
ProductId = npv.ProductId,
}).ToList(),
ImageObject = io
.Select(nio => new ImageObjectModel
{
Image = nio.Image.DtoToModel(),
IsDefault = nio.IsDefault,
ProductId = nio.ProductId
}).ToList(),
});
表:每个Products
有零个或多个ProductValues
,每个Product
只属于一个ProductValues
,即外键ProductValue
指向的Product
。
你想要(几个属性)所有Product
,每个ProductId
与其Products
。在那之后你Product
和ProductValues
,但那不是你的问题。
每当您想要“带有子项目的项目”时,例如“带学生的学校”,“带订单的客户”,“带订单行的订单”,请考虑使用DistinctBy
GroupJoin实际上是一个Left Outer Join,后面是GroupBy。
OrderBy
在您的情况下,您不希望GroupJoin两个序列,而是三个序列。你需要做一个额外的GroupJoin:
Enumerable.GroupJoin
这看起来很糟糕。因此,如果您必须更频繁地使用三个表进行GroupJoin,请考虑为三个表创建GroupJoin:
var productsWithTheirProductValues = products.GroupJoin( // GroupJoin Products
productValues, // with ProductValues
product => product.ProductId, // from every Product take the ProductId
productValue => productValue.ProductId, // from every ProductValue take the foreign key
// ResultSelector: take the product with its zero or more matching ProductValues
// to make a new object:
(product, productValuesOfThisProduct) => new
{
// Select only the product properties you plan to use:
Id = product.Id,
Name = product.Name,
Price = product.Price,
...
ProductValues = productValuesOfThisProduct
// only if you don't want all ProductValues of this product:
.Where(productValue => ...)
.Select(productValue => new
{
// again select only the properties you plan to use
Id = productValue.Id,
...
// not needed: the foreign key, you already know the value
// ProductId = productValue.ProductId,
})
.ToList(),
});
用法:
var result = products.GroupJoin(productValues,
product => product.ProductId,
productValue => productValue.ProductId,
// ResultSelector: remember the product and all its productValues
(product, productValuesOfThisProduct) => new
{
Product = product,
ProductValues = productValuesOfThisProduct,
})
// now do the 2nd join:
.GroupJoin(imageObjects,
firstJoinResult => firstJoinResult.Product.ProductId,
imageObject => imageObject.ProductId,
// result selector:
(firstJoinResult, imageObjectsOfThisProduct) => new
{
Product = firstJoinResult.Product,
ProductValues = firstJoinResult.ProductValues,
ImageObjects = imageObjectsOfThisProduct,
})
// take each element of this group join result and select the items that you want
.Select(joinResult => new
{
ProductId = joinResult.Product.ProductId,
Price = joinResult.Product.Price,
...
ProductValues = joinResult.ProductValues.Select(productValue => new
{
...
})
.ToList(),
ImageObjects = joinResult.ImageObjects.Select(imageObject => new
{
...
})
.ToList(),
});