0

我有一个包含约会的数据库。可以同时安排多个约会。我想检索不包括重复时间的可用预约时间列表。

编辑

例如我可以在我的数据库中

REQUEST_ID    REQUESTER_ID   APPOINTMENT_TIME
     1             0        30-JUN-13 03.30.00 AM
     2             1        30-JUN-13 03.30.00 AM
     3             0        30-JUN-13 03.30.00 AM
     4             0        30-JUN-13 03.30.00 AM
     5             3        30-JUN-13 03.35.00 AM
     6             0        30-JUN-13 03.45.00 AM
     7             0        30-JUN-13 03.45.00 AM

我想退货

REQUEST_ID    REQUESTER_ID   APPOINTMENT_TIME
     1             0        30-JUN-13 03.30.00 AM
     6             0        30-JUN-13 03.45.00 AM

结束编辑

此查询返回所有可用的预约空档

var data =
    (from a in db.FLU_SHOT
      where a.REQUESTER_ID == 0
      select a).ToArray();

此查询仅返回时间,我丢失了数据库中的其余信息

var times =
   (from a in data
    orderby Convert.ToDateTime(a.APPOINTMENT_TIME)
    select a.APPOINTMENT_TIME).Distinct().ToArray();

此查询返回与我的第一个查询相同的信息

var times =
   (from a in data
    orderby Convert.ToDateTime(a.APPOINTMENT_TIME)
    select a).Distinct().ToArray();

任何帮助将不胜感激。

4

3 回答 3

2

您正在寻找MoreLinqDistinctBy

var times =
   (from a in data
    orderby Convert.ToDateTime(a.APPOINTMENT_TIME)
    select a).DistinctBy(a => a.APPOINTMENT_TIME).ToArray();

或者,您可以使用基本GroupBy方法:

var times =
   (from a in data
    orderby Convert.ToDateTime(a.APPOINTMENT_TIME)
    select a).GroupBy(a => a.APPOINTMENT_TIME).Select(g => g.First()).ToArray();

或我的自定义 lambda 相等比较器(这比 快GroupBy,但比DistinctByServy 多次指出的要慢):

var times =
   (from a in data
    orderby Convert.ToDateTime(a.APPOINTMENT_TIME)
    select a).Distinct(PropertyEqualityComparer.GetNew(a => a.APPOINTMENT_TIME))
             .ToArray();

这是它的代码:

public class PropertyEqualityComparer<TObject, TProperty> 
    : IEqualityComparer<TObject>
{
    Func<TObject, TProperty> _selector;
    IEqualityComparer<TProperty> _internalComparer;
    public PropertyEqualityComparer(Func<TObject, TProperty> propertySelector,
        IEqualityComparer<TProperty> innerEqualityComparer = null)
    {
        _selector = propertySelector;
        _internalComparer = innerEqualityComparer;
    }
    public int GetHashCode(TObject obj)
    {
        return _selector(obj).GetHashCode();
    }
    public bool Equals(TObject x, TObject y)
    {
        IEqualityComparer<TProperty> comparer = 
            _internalComparer ?? EqualityComparer<TProperty>.Default;
        return comparer.Equals(_selector(x), _selector(y));
    }
}
//and here's a class to help instantiate it with anonymous objects
public static class PropertyEqualityComparer
{
    public static PropertyEqualityComparer<TObject, TProperty>
        GetNew<TObject, TProperty>(Func<TObject, TProperty> propertySelector)
    { 
        return new PropertyEqualityComparer<TObject, TProperty>
            (propertySelector);
    }
    public static PropertyEqualityComparer<TObject, TProperty>
        GetNew<TObject, TProperty>
        (Func<TObject, TProperty> propertySelector, 
        IEqualityComparer<TProperty> comparer)
    { 
        return new PropertyEqualityComparer<TObject, TProperty>
            (propertySelector, comparer);
    }
}
于 2013-07-23T15:38:50.510 回答
2

你可以使用GroupBy

var times = data.GroupBy(d => Convert.ToDateTime(d.APPOINTMENT_TIME))
    .Select(g => g.First())
    .ToArray();
于 2013-07-23T15:46:34.090 回答
1

每当我试图用 LINQ 完成某事(最终查询数据库),而答案并不明显时,我都会先编写 SQL 语句,然后再弄清楚如何将其转换为 LINQ。

如果您不知道如何进行翻译,那么您可以在网上找到一个工具来提供帮助,或者您可以将您的查询转换为存储的 proc 或 UDF 并从数据上下文中调用它。

在中等到高度复杂的查询中,手写几乎总是更好。很可能,无论 LINQ 输出什么,都不会针对您的特定场景进行优化。您通常可以诱使 LINQ 输出您想要的查询,但是到那时您已经浪费了很多宝贵的时间,这些时间本可以花在做其他更有效率的事情上。

编辑:为了更直接地回答您的问题,您似乎主要对 APPOINTMENT_TIMEs 感兴趣。在这种情况下,对该列进行分组,然后您可以遍历每个组并获取时间。

于 2013-07-23T15:40:55.503 回答