C#Linq查询返回多个匹配项

时间:2018-03-18 14:17:25

标签: c# linq

我想从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);
                }                  

            } 

我知道它不像单个查询那样高效或好看。但无法通过一个查询来实现此目的。如果有人可以将这些查询重写为一个查询。免费帮忙。我会很感激。

2 个答案:

答案 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