简体   繁体   English

IEnumerable的 <T> 以某种方式转换为EntitySet <T>

[英]IEnumerable<T> somehow gets transformed to EntitySet<T>

I have an hierarchy of classes that I fetch from database by LINQ to SQL controller and the display that big class as needed.Let me explain: 我有一个类的层次结构,我通过LINQ到SQL控制器从数据库中获取,并根据需要显示大类。让我解释一下:

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


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


Comment
//...some generic types

So in my controller I fetch big product and pass it to main view, then pass reviews in foreach to partial views and in each of these partial views I have another foreach that should list all comments as partial view. 因此,在我的控制器中,我获取大型产品并将其传递给主视图,然后将foreach中的评论传递给部分视图,并且在每个部分视图中,我有另一个foreach,应该将所有注释列为部分视图。

The types are defined clear as Ienumerable in classes and this dll worked fine with web forms,now when I hover my mouse over Comment in foreach loop in razor it says it's EntitySet instead of IEnumerable and I get "null exception: acessed context after disposed", that was the reason I am passing it as IEnumerable in first place as I fetch everything in one place. 这些类型在类中明确定义为Ienumerable,这个dll在Web表单中运行良好,现在当我将鼠标悬停在razor的foreach循环中的Comment时,它表示它是EntitySet而不是IEnumerable,我得到“null异常:处理后的acessed context”这就是我将它作为IEnumerable传递给我的原因,因为我在一个地方获取所有内容。 What could be the reason for such behaviour? 这种行为可能是什么原因? I didn't change anything in this dll that used to work fine with webforms. 我没有改变这个曾经与webforms一起工作的dll中的任何东西。

UPDATE: As I mentioned it worked fine with WebForms, I am calling .ToList() to get IEnumerable from IQueryable in when selecting data! 更新:正如我所提到的,它与WebForms一起工作正常,我在选择数据时调用.ToList()从IQueryable中获取IEnumerable!

Just because you declare it as IEnumerable<T> , that doesn't change the execution-time type. 仅仅因为您将其声明IEnumerable<T> ,这不会改变执行时类型。 So when you pass it over to your view, the view would know at compile-time that it's IEnumerable<T> but when you hover over it when debugging, you'll see the actual type. 因此,当您将其传递给视图时,视图将在编译时知道它是IEnumerable<T>但是当您在调试时将鼠标悬停在它上面时,您将看到实际类型。 (It's not clear at what point you were hovering over Comment in the razor view, but I strongly suspect it's in the middle of a debugging session.) (目前还不清楚你在剃须刀视图中徘徊在Comment哪一点,但我强烈怀疑它正处于调试会话的中间。)

If you want to take a copy of the data so that you can dispose the context, just call ToList() and return the result - that will be a List<T> instead. 如果要获取数据的副本以便可以处理上下文,只需调用ToList()并返回结果 - 这将是List<T>

Note that this compile-time/execution-time difference has nothing to do with LINQ or MVC really. 请注意,此编译时/执行时间差异与LINQ或MVC无关。 You can see the same thing extremely easily without anything complicated: 你可以非常轻松地看到同样的东西而不会有任何复杂

object value = "hello";

The compile-time type of value is object , which will stop you calling Substring etc on it. 编译时类型的valueobject ,它将阻止您在其上调用Substring等。 But if you hover over value in a debugging session (or look at it in the Watch or Local window) you'll see that the execution-time type is still string . 但是如果你将鼠标悬停在调试会话中的value (或者在Watch或Local窗口中查看它),你会发现执行时类型仍然是string

EDIT: From your edit: 编辑:从您的编辑:

I am calling .ToList() to get IEnumerable from IQueryable in when selecting data! 我在选择数据时调用.ToList()从IQueryable获取IEnumerable!

I'd really like to see that code, because I don't believe you're simply using something like: 我真的很想看到那些代码,因为我不相信你只是使用类似的东西:

return query.ToList();

If you're returning the result of calling ToList() , that won't be an EntitySet . 如果您返回调用ToList()的结果,那么它将不是 EntitySet

When you return a reference to an interface type, like IEnumerable<T> , the reference still points to the object whose run-time type implements the interface. 当您返回对接口类型的引用(如IEnumerable<T> ,引用仍指向其运行时类型实现接口的对象。 More generally, whenever you refer to an object through an interface that it implements, or through a base class in its inheritance chain, you're still referring to an instance of the object's most-derived type. 更一般地说,每当通过它实现的接口或通过其继承链中的基类引用对象时,您仍然指的是该对象的派生类型最多的实例。

For example: 例如:

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());

Output: 输出:

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

If you want to copy the data to another object that also implements IEnumerable<T> , you need to write some code to do that. 如果要将数据复制到另一个也实现IEnumerable<T>对象,则需要编写一些代码来执行此操作。 As others have suggested, calling ToList() is an easy way to achieve this. 正如其他人所建议的那样,调用ToList()是实现这一目标的简单方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM