【问题标题】:IEnumerable<T> somehow gets transformed to EntitySet<T>IEnumerable<T> 以某种方式转换为 EntitySet<T>
【发布时间】:2012-04-12 08:38:48
【问题描述】:

我有一个层次结构的类,我通过 LINQ to SQL 控制器从数据库中获取,并根据需要显示那个大类。让我解释一下:

BigProduct
IEnumerable<Review>
//...some generic types


Review
IEnumerable<Comment>
//...some generic types


Comment
//...some generic types

所以在我的控制器中,我获取大产品并将其传递给主视图,然后将 foreach 中的评论传递给部分视图,在每个部分视图中,我都有另一个 foreach 应该将所有 cmets 列为部分视图。

类型在类中被明确定义为 Ienumerable,并且此 dll 在 Web 表单中运行良好,现在当我将鼠标悬停在 razor 的 foreach 循环中的 Comment 上时,它说它是 EntitySet 而不是 IEnumerable,并且我得到“空异常:访问的上下文处置后”,这就是我首先将它作为 IEnumerable 传递的原因,因为我将所有内容都放在一个地方。这种行为的原因可能是什么?我没有更改这个 dll 中的任何内容,这些内容过去可以与 web 表单一起正常工作。

更新:正如我提到的,它在 WebForms 上运行良好,我在选择数据时调用 .ToList() 从 IQueryable 中获取 IEnumerable!

【问题讨论】:

    标签: c# asp.net linq-to-sql asp.net-mvc-4


    【解决方案1】:

    仅仅因为您将其声明IEnumerable&lt;T&gt;,这不会改变执行时间类型。所以当你把它传递给你的视图时,视图会在编译时知道它是IEnumerable&lt;T&gt;,但是当你在调试时将鼠标悬停在它上面时,你会看到实际的类型。 (尚不清楚您在剃刀视图中将鼠标悬停在 Comment 上的哪个时间点,但我强烈怀疑它正处于调试会话的中间。)

    如果您想获取数据的副本以便处理上下文,只需调用 ToList() 并返回结果 - 将改为 List&lt;T&gt;

    请注意,这种编译时间/执行时间差异实际上与 LINQ 或 MVC 无关。您可以非常轻松地看到相同的东西,而无需任何复杂的东西:

    object value = "hello";
    

    valuecompile-time 类型是 object,这将阻止你调用 Substring 等。但是,如果您在调试会话中将鼠标悬停在 value 上(或在 Watch 或 Local 窗口中查看),您会看到执行时间类型仍然是 string

    编辑:根据您的编辑:

    在选择数据时,我正在调用 .ToList() 从 IQueryable 中获取 IEnumerable!

    我真的很想看看那个代码,因为我不相信你只是在使用类似的东西:

    return query.ToList();
    

    如果您返回调用ToList() 的结果,那不会EntitySet

    【讨论】:

    • 去死吧,乔恩,你真的让我失望了!这并不是说您需要更多的代表,而是您不断地抛出这些快速、正确且易于理解的答案!这让我别无选择,只能对你的答案投赞成票。啊!
    • @DanielPratt:知道早餐后的点赞不太可能影响我的代表,这会让你感觉更好吗?
    • 大声笑我发现问题出在哪里我试图循环 Review.Comments 是 Table.. 而不是 Review.cmets 这是我班级的财产。无论如何感谢您的澄清!
    【解决方案2】:

    当您返回对接口类型的引用时,例如IEnumerable&lt;T&gt;,该引用仍然指向其运行时类型实现该接口的对象。更一般地说,每当您通过对象实现的接口或通过其继承链中的基类引用对象时,您仍然是在引用对象的最派生类型的实例。

    例如:

    object o1 = new object();
    object o2 = "I am a string.";
    object o3 = 42;
    
    Console.WriteLine(o1.GetType());
    Console.WriteLine(o2.GetType());
    Console.WriteLine(o3.GetType());
    
    IComparable ic1 = "I am a string.";
    IComparable ic2 = 42;
    
    Console.WriteLine(ic1.GetType());
    Console.WriteLine(ic2.GetType());
    

    输出:

    System.Object
    System.String
    System.Int32
    System.String
    System.Int32
    

    如果您想将数据复制到另一个也实现IEnumerable&lt;T&gt; 的对象,您需要编写一些代码来执行此操作。正如其他人所建议的那样,致电ToList() 是实现此目的的一种简单方法。

    【讨论】:

      猜你喜欢
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 1970-01-01
      • 2021-12-02
      • 2011-08-22
      相关资源
      最近更新 更多