[英]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.