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
真的只是一种解决方法,就像杀死大象和分块加载一样。
我正在构建一个简单的旅游预订应用程序。
它有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
真的只是一种解决方法,就像杀死大象和分块加载一样。