LINQ中如何用DateTimeOffset类型复合外键关联两张表?
关于LINQ中DateTimeOffset复合外键关联的疑问解答
1. 是否需要使用DateTimeOffset.Compare()?
不需要直接使用DateTimeOffset.Compare()。
原因是:DateTimeOffset类型本身已经重载了相等运算符(==)和Equals方法,会正确比较两个实例是否代表同一个UTC时间点(即忽略时区偏移差异,只要转换为UTC后的时间一致,就会判定为相等)。而LINQ中匿名类型的相等比较会逐个检查其属性的相等性,所以你当前的查询写法:
on new { o.ExpectedDeliveryDate, o.JobNumber } equals new { d.ExpectedDeliveryDate, d.JobNumber }
已经可以正确完成复合键的匹配,无需额外调用Compare方法。
2. 如果需要使用DateTimeOffset.Compare(),该如何操作?
只有当你需要自定义比较逻辑(比如要求本地时间和时区偏移完全一致才匹配,或者需要基于时间先后的排序关联)时,才需要用到DateTimeOffset.Compare()。
此时无法直接在join的on子句中使用Compare,可以改用where子句配合方法语法实现关联:
示例:用where子句实现自定义匹配(要求本地时间+偏移完全一致)
from o in outstandingOrders from d in dispatchAdvicedOrders .Where(d => DateTimeOffset.Compare(o.ExpectedDeliveryDate, d.ExpectedDeliveryDate) == 0 && o.JobNumber == d.JobNumber) .DefaultIfEmpty() select new DeliverySchedule { ExpectedDeliveryDate = o.ExpectedDeliveryDate, JobNumber = o.JobNumber, OutstandingWeight = o.Weight, DispatchAdvicedWeight = d?.Weight };
这里DateTimeOffset.Compare(a, b)返回0表示两个实例的本地时间和时区偏移完全相同(区别于默认的相等比较,默认只看UTC时间)。
如果需要复用比较逻辑,也可以实现IEqualityComparer<YourCompositeKey>(其中YourCompositeKey是包含ExpectedDeliveryDate和JobNumber的实体类),在Equals方法中调用DateTimeOffset.Compare来判断时间部分的相等性,再在GroupJoin中传入该比较器,不过这种写法相对复杂,仅在有复用需求时推荐。
内容的提问来源于stack exchange,提问作者Lakshitha Kanchana
相关产品推荐
相关产品推荐

