我想从Boat
表中获取一个船项只有当该船不在RentBoat
表中并且IsOnRent
列上的值设置为真时。
到目前为止,这是我的代码:
db.Boats.SingleOrDefault(x => !db.RentBoats.Any(s => s.BoatID == x.BoatID && s.IsOnRent == true));
我得到的错误是:
序列包含几个元素
我的代码在哪里错了?任何帮助都会很棒。
基本上我想要这个查询做什么,但我希望它从Id返回匹配的项目或返回null。(一个单项不是列表)
db.Boats.Where(boat => !db.RentBoats.Any(x => x.BoatID == boat.BoatID && x.IsOnRent == true)).ToList();
public class Boat
{
[Key]
public int BoatID { get; set; }
public string BoatName { get; set; }
}
public class RentBoat
{
[Key]
[Required]
public int RentBoatID { get; set; }
[ForeignKey("Boat")]
public int BoatID { get; set; }
public string BoatName { get; set; }
public bool IsOnRent { get; set; }
public virtual Boat Boat { get; set; }
}
修改
这就是我最终解决的问题:
using (var db = new BoatContext())
{
List<RentBoat> IsBoatRented = db.RentBoats.Where(x => x.BoatID == boatId && x.IsOnRent == true).ToList();
if (IsBoatRented.Count() == 0)
{
returnedBoat = db.Boats.FirstOrDefault(x => x.BoatID == boatId);
}
}
我知道它不像单个查询那样高效或好看。但无法通过一个查询来实现此目的。如果有人可以将这些查询重写为一个查询。免费帮忙。我会很感激。
答案 0 :(得分:1)
通过使用SingleOrDefault
,您说应该只有一条记录符合条件。该错误表示数据库中有多行符合您的要求。
如果你想要一个结果,但是如果只有一个成功的匹配,请不要使用FirstOrDefault
。如果有一个或多个匹配谓词的记录,则返回一行;如果没有,则返回null
。
答案 1 :(得分:1)
你应该尝试这样做,得到所有非租用船只(你的查询可能会给你多次相同的船只)并避免那个appply组
var allNotRendedBoats= from b in db.Boats
.Where(boat => !db.RentBoats
.Any(x => x.BoatID == boat.BoatID && x.IsOnRent == true))
group b by b.BoatID into g
select g.First();
如果它不会多次返回同一艘船而不是仅仅放置条件而不是SingleOrDefault
给你输出
似乎与!
条件
db.Boats.SingleOrDefault(x =>
!db.RentBoats.Any(s => s.BoatID == x.BoatID && s.IsOnRent == true));
应该是
db.Boats.SingleOrDefault(x =>
db.RentBoats.Any(s => s.BoatID == x.BoatID && s.IsOnRent == true));
如果您执行!
,则会要求您提供多个元素
因此,如果我查看您的代码,那么您似乎要求所有未处理此条件的元素!db.RentBoats.Any(s => s.BoatID == x.BoatID && s.IsOnRent == true))
SingleOrDefault
非常有用
如果你想获得第一个元素,那么我建议使用FirstOrDefault