不确定这个代码,有代码味道!

时间:2011-01-17 19:11:35

标签: c# asp.net linq

这段代码让我烦恼,

我创建了一个单独的对象EventDistance,但我认为它可能不需要,它只是我不知道如何以不同的方式编码它。距离是我添加到Event的部分类的属性。基本上我想要返回所有事件并按距离排序。

我认为额外一轮的foreach可能是不必要的。

public IQueryable<Event> FindByLocation(float latitude, float longitude)
        {

            var eventsList = from ev in GetAllEvents()
                             join i in db.NearestEvents(latitude, longitude)
                             on ev.ID equals i.ID
                             select new EventDistance() { TheEvent = ev, Distance = i.Distance };


            foreach (var item in eventsList)
            {
                item.TheEvent.Distance = item.Distance;  
            }
            return eventsList.OrderBy(e => e.Distance).Select(e => e.TheEvent);
        } 

4 个答案:

答案 0 :(得分:1)

从我所看到的,您不应该需要EventDistance课程。只需省略它,并通过不在LINQ表达式中指定任何类型来使用匿名类型:

public IQueryable<Event> FindByLocation(float latitude, float longitude)
    {

        var eventsList = from ev in GetAllEvents()
                         join i in db.NearestEvents(latitude, longitude)
                         on ev.ID equals i.ID
                         select new { TheEvent = ev, Distance = i.Distance };


        foreach (var item in eventsList)
        {
            item.TheEvent.Distance = item.Distance;  
        }
        return eventsList.OrderBy(e => e.Distance).Select(e => e.TheEvent);
    } 

答案 1 :(得分:1)

我对LINQ语法一无所知,但实际上应该可以填充第一个select中的距离值。像

这样的东西
var eventsList = from ev in GetAllEvents()
                 join i in db.NearestEvents(latitude, longitude)
                 on ev.ID equals i.ID
                 orderby i.Distance
                 select (ev => { ev.Distance = i.Distance; return ev; });

?或者,写得正确: - )

var eventsList = GetAllEvents()
                 .Join(db.NearestEvents(latitude, longitude),
                       ev => ev.ID,
                       i => i.ID,
                       (ev, i) => { ev.Distance = i.Distance; return ev; })
                 .OrderBy(ev => ev.Distance);

N.B。正如下面的qstarin注释,只有当我们在此时对象进行操作时,才有可能这样做,而不是被评估为SQL的ORM对象。也就是说,你可能仍然可以

  1. 在初始提取中执行orderby
  2. 强迫对象进入内存(我忘记了最好的方法)
  3. 使用单个选择将对象组合到Event对象中,而不是上面的循环

答案 2 :(得分:1)

如果你想把它保存为IQueryable,你可以这样做:

        public IQueryable<Event> FindByLocation(float latitude, float longitude)
        {

            return from ev in GetAllEvents()
                   join i in db.NearestEvents(latitude, longitude)
                   on ev.ID equals i.ID
                   order by i.Distance
                   select ev;
        }

只要GetAllEvents()方法返回IQueryable也是如此。

编辑:我现在已经尝试过以下Rup的建议,你应该能够在不调用此方法的db调用的情况下返回IQueryable。像这样:

        public IQueryable<EventDistance> FindByLocation(float latitude, float longitude)
        {
                return from ev in GetAllEvents()
                   join i in db.NearestEvents(latitude, longitude)
                   on ev.ID equals i.ID
                   orderby i.Distance
                   select new EventDistance
                   {
                       Event = ev,
                       Distance = i.Distance
                   };
       }

不需要映射EventDistance类。

答案 3 :(得分:1)

你可以这样做吗?

public IQueryable<Event> FindByLocation(float latitude, float longitude)
    {

        var eventsList = from ev in GetAllEvents()
                         join i in db.NearestEvents(latitude, longitude)
                         on ev.ID equals i.ID
                         select new Event { ID = ev.ID, Distance = i.Distance };


        return eventsList.OrderBy(e => e.Distance).AsQueryable();
    }