繁体   English   中英

如何根据多种条件找到Linq的特定项目?

[英]How to find specific item with Linq based on multiple conditions?

我有一个非常简单的查询:

//user from UserManager from default AccountController from .net Identity
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());

var product = await Task.Run(() 
    => db.WatchedProducts.Where(u => u.ApplicationUserId == user.Id && u.ProductId == id));

我想要做的是在WatchedProducts列表中找到特定product 它的模型看起来像这样:

public class WatchedProduct
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("ApplicationUser")]
    public string ApplicationUserId { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }

    [ForeignKey("Product")]
    public int ProductId { get; set; }
    public virtual Product Product { get; set; }
}

ApplicationUser具有WatchedProducts列表。

我的问题是,为什么获得WatchedProduct product获得IQueryable<WatchedProduct> product

这是因为你使用方法Where() Where()方法根据您的lambda-expression => u.ApplicationUserId == user.Id && u.ProductId == id过滤您的数据并返回IQueryable<TSource>IEnumerable<TSource> (请参阅Reza Aghaei的回答中的重要解释)。

如果您想获得WaterProduct产品,那么只需通过FirstOrDefault()方法获取它:

var product = await Task.Run(() 
    => db.WatchedProducts.Where(u => u.ApplicationUserId == user.Id && u.ProductId == id)
       .FirstOrDefault());

您没有获得任何数据,因为您没有实现您的查询。 它被称为延迟执行。 延迟执行意味着在您需要必要的数据之前,您的linq代码不会在数据库中执行。 因此,为了实现数据或在数据库中执行查询,您应该调用以下方法:

foreach, toList(), First(), FirstOrDefault(), Single(), SingleOrDefault(), etc...

这是因为Where扩展方法返回IEnumerable<TSource> 在db set的情况下,它返回IQueryable<TSource> ,它是IEnumerable<TSource>

在您的情况下,由于您使用的是async / await模式,因此可以使用FirstOrDefaultAsync来获取单个项目:

var p = await db.WatchedProducts.FirstOrDefaultAsync(u => u.ApplicationUserId == user.Id &&
                                                          u.ProductId == id)

您应该使用SingleOrDefault

从我可以告诉你的结果应该是唯一的,因为你使用的产品ID是独一无二的

var product = await Task.Run(() 
    => db.SingleOrDefault(u => u.ApplicationUserId == user.Id && u.ProductId == id));

这将返回一个项目,如果没有找到则返回null。 注意,如果找到多个项目,它将抛出异常,因为产品ID很可能是唯一的,如果它找到的更多,你会知道你在数据库中搞砸了你有多个产品同样的身份

如果它可以接受该查询可以有多个记录作为结果然后使用FirstOrDefault而不是SingleOrDefault但是逻辑不是很正确,因为有一个查询需要返回一个或没有,返回列表中的第一个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM