C# 使用LINQ查询语法EF Core C的左外部联接#
我有一个关于以下内容的问题C# 使用LINQ查询语法EF Core C的左外部联接#,c#,sql,entity-framework,linq,asp.net-core,C#,Sql,Entity Framework,Linq,Asp.net Core,我有一个关于以下内容的问题 未通过外键连接的两个表的左外连接 按第二个表中匹配的结果排序 我希望这是在LINQ查询方法语法中完成的,因为我正在根据随skip和limit一起提供的输入添加大量条件 如果我们有以下产品和最喜欢的表格 所以我想要的结果是: 这意味着收藏夹作为第一组的一部分,而不是收藏夹应该在它们后面。下面是我所做的尝试。 我能够连接表以获得输出,但不确定如何确保在第一页中获得所有FAV 这个答案与我的想法非常接近,但它得到了结果,然后进行排序,这在我的情况下是不可能的,因为我正
[Table("Product")]
public class ProductModel
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ProductId { get; set; }
public string ProductName {get; set;}
public bool IsFavorite { get; set; }
}
[Table("UserFavorite")]
public class UserFavoriteModel
{
[Required]
public Guid UserId { get; set; }
[Required]
public Guid Identifier { get; set; }
[Required]
public FavoriteType Type { get; set; }
}
// Gets products
private async Task<List<ProductModel>> GetProductsAsync(
Guid categoryId,
Guid subCategoryId,
int from,
int limit)
{
var query = _context.Products.AsQueryable();
if (!string.IsNullOrEmpty(categoryId))
query = query.Where(product => product.CategoryId == categoryId);
if (!string.IsNullOrEmpty(subCategoryId))
query = query.Where(product => product.SubCategoryId == subCategoryId);
query = query.Skip(from).Take(limit);
var products = await query.ToListAsync();
query = query.GroupJoin(
_context.Favorites.AsNoTracking()
.Where(favorite => favorite.Type == FavoriteType.FASHION)
// This user Id will come from context just adding for overall picture.
.Where(favorite => favorite.UserId == userId),
//This orderby if I add will not make any difference.
//.OrderByDescending(favorite => favorite.Identifier),
v => v.ProductId,
f => f.Identifier,
(product, fav) => new { product, fav }).
SelectMany(x => x.Fav.DefaultIfEmpty(),
(x, y) => SetFavorite(x.Project, y));
}
private static ProductModel SetFavorite(ProductModel v, UserFavoriteModel si)
{
v.IsFavorite = (si != null);
return v;
}
[表格(“产品”)]
公共类产品模型
{
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
公共Guid ProductId{get;set;}
公共字符串ProductName{get;set;}
公共bool是收藏夹{get;set;}
}
[表格(“用户收藏夹”)]
公共类UserFavoriteModel
{
[必需]
公共Guid用户标识{get;set;}
[必需]
公共Guid标识符{get;set;}
[必需]
公共FavoriteType类型{get;set;}
}
//获取产品
专用异步任务GetProductsAsync(
Guid类别ID,
Guid子类别ID,
int from,
整数限制)
{
var query=_context.Products.AsQueryable();
如果(!string.IsNullOrEmpty(categoryId))
query=query.Where(product=>product.CategoryId==CategoryId);
如果(!string.IsNullOrEmpty(子类别ID))
query=query.Where(product=>product.SubCategoryId==SubCategoryId);
query=query.Skip(from).Take(limit);
var products=await query.ToListAsync();
query=query.GroupJoin(
_context.Favorites.AsNoTracking()
.Where(favorite=>favorite.Type==FavoriteType.FASHION)
//此用户Id将来自上下文,仅用于添加整体图片。
.Where(favorite=>favorite.UserId==UserId),
//如果我添加此orderby,将不会产生任何影响。
//.OrderByDescending(收藏夹=>favorite.Identifier),
v=>v.ProductId,
f=>f.标识符,
(产品,fav)=>新{产品,fav})。
选择many(x=>x.Fav.DefaultIfEmpty(),
(x,y)=>SetFavorite(x.Project,y));
}
私有静态ProductModel SetFavorite(ProductModel v,UserFavoriteModel si)
{
v、 IsFavorite=(si!=null);
返回v;
}
我会这样做:
var query =
_context.Products.AsQueryable().Select(p => new ProductModel {
ProductId = p.ProductId,
ProductName = p.ProductName,
IsFavorite =
_context.Favorites.Any(f =>
f.Identifier = p.ProductId &&
f.Type == FavoriteType.FASHION &&
f.UserId == userId
)
}).OrderByDescending(favorite => favorite.Identifier);
AsNoTracking内部投影,没有返回记录-这对我来说是新事物;)@阿杜奇,非常感谢。这看起来比我想象的要简单,要学的东西很多:)。有一些打字错误可能对其他人有用f.Identifier=p.ProductId(应该有==),并且顺序应该是OrderByDescending(favorite=>favorite.IsFavorite)。如果我在ProductModel中有大量字段,我有一个小小的澄清,那就是有没有一种方法可以简化它,而不是在select中声明所有字段。我尝试了选择(p=>{p.IsFavorite=favs condition here;return p;}),但我认为表达式中不支持该选项。@SvyatoslavDanyliv我只是将此方法发布到SO中,但忘记添加返回部分:)。据我所知,AsNoTracking仅用于读取,我甚至将其用于_context.Products.AsNoTracking,是否有我不应该使用的原因。这是因为IQueryable?
AsNoTracking
用于“通知”ChangeTracker不注册加载的实体。如果您没有获得记录,只需计数
或任何
,等等-因此没有任何更改跟踪。