【问题标题】:Linq VAR and Typed ObjectLinq VAR 和类型化对象
【发布时间】:2011-03-03 14:06:49
【问题描述】:

我想要一个代码示例。 目前我在 c# 和 asp.net 4 ef4 中使用 linq

       var querySlotOrder = from slot in context.CmsSlots
                             where slot.SlotId == myCurrentSlotId
                             select slot;

           if (querySlotOrder.SlotOrder == myNewSlotOrder)
                e.Cancel = true;

这个 linq 查询只返回一条记录。

使用 VAR 我无法获取类型化对象,也无法访问其属性 SlotOrder。

如何更改查询?感谢您的帮助

关于该主题的有用资源:

http://msdn.microsoft.com/en-us/library/bb384065.aspx

http://msdn.microsoft.com/en-us/library/bb397947.aspx

http://msdn.microsoft.com/en-us/library/bb397678.aspx

【问题讨论】:

  • 与 var 一样正常 - 如果您不使用它,就不会出现问题。

标签: c# asp.net linq entity-framework


【解决方案1】:

即使您的查询返回单个对象,您在幕后使用的 Select 方法也不会。它在 EF 中返回 IQueryable<T>

如果要存储单个对象,则应使用SingleSingleOrDefaultFirstFirstOrDefault 等方法。

var querySlotOrder = (from slot in context.CmsSlots
                      where slot.SlotId == myCurrentSlotId
                      select slot).Single();

四种方法的区别在于:

  • Single:返回序列中唯一的元素,如果序列中不完全是一个元素,则抛出异常。
  • SingleOrDefault:返回序列的唯一元素,如果序列为空则返回默认值;如果序列中有多个元素,此方法将引发异常。
  • First:返回序列的第一个元素。
  • FirstOrDefault:返回序列的第一个元素,如果序列不包含任何元素,则返回默认值。

(来自MSDN的定义)

【讨论】:

  • 不客气。这里最重要的是要记住,正如 Aasmund 在他的回答中所说,var 不是类型,而是在编译时被从右侧表达式推断的类型替换 - 当使用 Select来自 EF 的方法,这将是一个 IQueryable<T>IEnumerable<T> 与 Linq 到对象);当使用Single 或其他方法时,您会得到T
  • 再次感谢您的评论。它帮助我掌握了这个概念。再见
【解决方案2】:

LINQ select-statement 总是返回一个可查询的集合。因此,您需要从中获取单个对象。

var querySlotOrder = (from slot in context.CmsSlots
                      where slot.SlotId == myCurrentSlotId
                      select slot).FirstOrDefault();

【讨论】:

    【解决方案3】:

    返回对象的类型是IQueryable<CmdSlot>(假设CmdSlot是元素的类型),querySlotOrder得到那个类型(这就是var的效果;var本身不是类型)。如果您绝对确定结果集合中始终只有一个元素,您可以使用querySlotOrder.Single() 检索它。

    【讨论】:

      【解决方案4】:

      linq 查询返回的不是记录,而是只有一个元素的记录集合。如果要获取第一个元素并且确定集合中只有 1 个元素,请使用 Single 扩展方法:

      var querySlotOrders = from slot in context.CmsSlots
                            where slot.SlotId == myCurrentSlotId
                            select slot;
      var querySlotOrder = querySlotOrders.Single();
      
      if (querySlotOrder.SlotOrder == myNewSlotOrder)
          e.Cancel = true;
      

      【讨论】:

        【解决方案5】:

        正如丹尼斯在他的回答中指出的那样,您没有得到一个对象的实例,而是从查询中得到一个 IEnumerable。为了访问 SlotOrder 属性,您需要从集合中选择一个特定的项目,很可能是第一个 - 根据您的查询来判断。

        【讨论】:

          【解决方案6】:

          这是 madd0 的代码,但重新改写为使用 C# 样式而不是 SQL 样式

          var querySlotOrder = context.CmsSlots
            .Where(slot => slot.SlotId == myCurrentSlotId)
            .Single();
          

          最好阅读和理解whan SQL风格

          【讨论】:

            【解决方案7】:

            你为什么使用var?如果你知道你期望的对象的类型,你应该输入querySlotOrder

            MyObjectType querySlotOrder = (from slot in context.CmsSlots
                                         where slot.SlotId == myCurrentSlotId
                                         select slot).FirstOrDefault();
            
                       if (querySlotOrder.SlotOrder == myNewSlotOrder)
                            e.Cancel = true;
            

            【讨论】:

            • 你不是在回答他的问题,而是在质疑他的风格。许多人使用 var,包括许多 Linq 示例。它没有错。无论如何,你的代码是不正确的。
            • 这不会编译。假设每个槽项都是 MyObjectType 类型,结果查询将是 IQueriable 类型,而不是 MyObjectType。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-18
            相关资源
            最近更新 更多