Linq 查询嵌套 3 个表和 select 某些记录

Linq query to nest 3 tables and select certain records

我正在构建一个简单的旅游预订应用程序。

它有3个链接表,设置如下。

给定一个特定的 TourCategoryId 和一个日期 (dte),我正在尝试构建一个对象,然后我可以继续用它来填充视图模型。

但是我不明白如何根据 dte 检查 TourDate 字段。

我是否试图在一个声明中做太多事情?谁能帮我解决我认为简单的查询问题?

感谢任何建议:

我的 linq 是:

var tours = db.Tours
            .Include(x => x.TourDate)
            .Include(x => x.TourDate.Select(b => b.Booking))
            .Where(t => t.TourCategoryId == id &&
                        t.TourDate.Any(td => td.Date==dte));

(也是伪代码)

            .Where(v => v.Booking.NumberBooked.Sum() < v.Tours.PlacesAvailable)

我已经根据下面的建议对此进行了更新,但它返回了所有 td.Date - 而不是过滤,正如您从下面的屏幕截图中看到的那样,显示了返回的所有 3 条记录,而不仅仅是那些 td.Date =16=]:

是不是 .Any 可能不正确?

最终结果应该是

游览列表 => 日期列表 => 预订列表 - 日期被过滤到 dte 例如:

Tour1- night tours
--TourDate - filtered to 02/03/2015
----Booking1
----Booking2
----Booking3
Tour2- day tours
--TourDate - filtered to 02/03/2015
----Booking1
----Booking2
Tour3- multi-day tours
--TourDate - filtered to 02/03/2015
----Booking1
----Booking2
----Booking3
----Booking4

再次感谢马克

public class Tour
{
    public int TourId { get; set; }
    public int TourCategoryId { get; set; }
    public string TourName { get; set; }
    public int PlacesAvailable { get; set; }
    public virtual ICollection<TourDate> TourDate { get; set; }
}

public class TourDate
{
    public int TourDateId { get; set; }
    public int TourId { get; set; }
    public DateTime Date { get; set; }
    public virtual Tour Tour { get; set; }
    public virtual ICollection<Booking> Booking { get; set; }
}

public class Booking
{
    public int BookingId { get; set; }
    public int TourDateId { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public int NumberBooked { get; set; }
    public virtual TourDate TourDate { get; set; }
}

据我了解,您想要 TourCategoryId 中的任何 Tour,它在 dte 上有一个 TourDate

这可能对你有用。

var tours =
    db.Tours
        .Include(x => x.TourDate)
        .Include(x => x.TourDate.Select(b => b.Booking))
        .Where(t => t.TourCategoryId == id &&
                    t.TourDate.Any(td => td.Date == dte));

筛选TourDate.

foreach(var tour in tours)
{
    tour.TourDate = tour.TourDate.Where(td => td.Date == dte).ToList()
}

您面临的问题是您使用的业务对象不适合您使用的 class 层次结构。

尽量不要严格使用映射的数据库 classes。在这种情况下,您的业务对象不同于与数据库结构匹配的 Tour class 的实例列表。在您创建的所有导航属性的帮助下,只需使用 db classes 来形成查询,但不要尝试将您需要的所有查询都放入与您需要的相同 class 层次结构中查看模型。

您应该围绕预订而不是游览构建查询。 select 符合您条件的预订,包括伪代码中的预订,然后按日期和旅游和 select 某种代表组的匿名对象分组。然后将它们转换为您需要的视图模型 classes,不需要所有这些都映射到数据库。

在许多情况下,您甚至不需要为了让一些 属性 加载而对实体进行水合。

不需要装大象就可以拍照。 Include 真的只是一种解决方法,就像杀死大象和分块加载一样。