繁体   English   中英

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

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

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

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


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


Comment
//...some generic types

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

这些类型在类中明确定义为Ienumerable,这个dll在Web表单中运行良好,现在当我将鼠标悬停在razor的foreach循环中的Comment时,它表示它是EntitySet而不是IEnumerable,我得到“null异常:处理后的acessed context”这就是我将它作为IEnumerable传递给我的原因,因为我在一个地方获取所有内容。 这种行为可能是什么原因? 我没有改变这个曾经与webforms一起工作的dll中的任何东西。

更新:正如我所提到的,它与WebForms一起工作正常,我在选择数据时调用.ToList()从IQueryable中获取IEnumerable!

仅仅因为您将其声明IEnumerable<T> ,这不会改变执行时类型。 因此,当您将其传递给视图时,视图将在编译时知道它是IEnumerable<T>但是当您在调试时将鼠标悬停在它上面时,您将看到实际类型。 (目前还不清楚你在剃须刀视图中徘徊在Comment哪一点,但我强烈怀疑它正处于调试会话的中间。)

如果要获取数据的副本以便可以处理上下文,只需调用ToList()并返回结果 - 这将是List<T>

请注意,此编译时/执行时间差异与LINQ或MVC无关。 你可以非常轻松地看到同样的东西而不会有任何复杂

object value = "hello";

编译时类型的valueobject ,它将阻止您在其上调用Substring等。 但是如果你将鼠标悬停在调试会话中的value (或者在Watch或Local窗口中查看它),你会发现执行时类型仍然是string

编辑:从您的编辑:

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

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

return query.ToList();

如果您返回调用ToList()的结果,那么它将不是 EntitySet

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

例如:

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<T>对象,则需要编写一些代码来执行此操作。 正如其他人所建议的那样,调用ToList()是实现这一目标的简单方法。

暂无
暂无

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

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