如何使用 Linq 返回包含列的结果集
我在一个类中有一个函数,它将运行 Linq to Entities 查询(或实际上任何类型的 Linq 查询),并且它将在结果集中返回 2 列。我想向调用我的函数的人返回一个对象,这将使 Intellisense 知道我返回的内容。
让我解释一下。如果我有一个这样的函数:
public static IQueryable GetInfo(MyEntityModel oEntityModel)
{
var query =
(from t in oEntityModel.Table1
from u in t.Table2
where t.Status == true &&
u.Status == true
select new
{
t.Column1,
u.Column2
})
return query;
}
我可以(应该)用什么来代替 IQueryable,以便调用我的 GetInfo 函数的人都能从结果集中获取 Intellisense,并显示它有 Column1 和 Column2?
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
if (linqresult.Column1 == 1)
{
foreach (var oItem in linqresult)
{
.. do stuff...
}
}
塔克斯
I have a function inside a class that will run a Linq to Entities query (or any type of Linq query actually), and it's gonna return 2 columns in the resultset. I would like to return an object to whoever is calling my function that will allow Intellisense to know what I have returned.
Let me explain. If I have a function like this:
public static IQueryable GetInfo(MyEntityModel oEntityModel)
{
var query =
(from t in oEntityModel.Table1
from u in t.Table2
where t.Status == true &&
u.Status == true
select new
{
t.Column1,
u.Column2
})
return query;
}
What can (should) I put instead of IQueryable so that whoever calls my GetInfo function, will get Intellisense from the resultset, and show that it has a Column1 and Column2?
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
if (linqresult.Column1 == 1)
{
foreach (var oItem in linqresult)
{
.. do stuff...
}
}
Tks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您不能从函数返回匿名类型,它们是严格的“内联”类。当您返回它时,foreach 循环将只能将结果解释为普通对象。我想您可以使用反射来查询属性名称和值,但是定义数据传输类型来保存结果似乎更直接。
请参阅此问题和此博客发布。
因此,您可以创建一个简单的结构或类:
然后在函数中修改您的查询:
类似的东西应该可以工作。请注意,我在 MyDataResult 中使用“对象”作为属性。我不知道您返回的列的类型,您应该使用实际类型以获得完整的智能感知。
You cannot return an anonymous type from a function, they are strictly "inline" classes. When you return it, the foreach loop will only be able to interpret the result as an plain object. I guess you could use reflection to query the property names and values, however it seems much more straight forward to define a data transfer type to hold the results.
See this question, and this blog post.
So you could create a simple struct or class:
Then modify your query in the function:
Something like that should work. Note that I used "object" for the properties in MyDataResult. I don't know the types of the columns you are returning, you should use the actual types in order to get full intellisense.
您正在返回匿名类型的集合,它们将被转换为对象,因此当您尝试迭代它们时,尽管它们将是您的对象(并且它们将包含您的属性),但在编译时它们将被转换为对象
:可以在此处阅读更多相关信息。
如果您想拥有智能感知,我建议您创建一个自定义类,它们将保存您的属性,并且返回的不是匿名类型(使用
new {}
),而是您的类的对象(new MyClass(道具1,道具2)
)。您还需要更改方法的签名,以便它返回IQueryable
而不仅仅是普通的非泛型IQueryable
。You are returning a collection of anonymous types, they will be casted to objects, so when you try to iterate over them, altough they will be your objects (and they will contain your properties) at compile time they will be casted to objects:
You can read more about it here.
If you want to have intellisense, I suggest you create a custom class they will hold your properties and return not an anonymous type (using
new {}
) but object of your class (new MyClass(prop1, prop2)
). You also need to change signature of your method, so it returnsIQueryable<YourClass>
and not just plain non-genericIQueryable
.正如其他人所说,创建一种新类型来容纳两列通常是最好的选择。
但是,如果由于某种原因您不想这样做并且您正在使用 .Net 4.0,则可以使用
Tuple
:As others have said, creating a new type to hold the two columns is usually the best option.
But if, for some reason, you don't want to do that and you are using .Net 4.0, you can use
Tuple
:当您返回结果集 AsQueryable 时,应用程序已经能够为您提供智能感知,但是在您的示例中,如果您知道您的集合只有一行,则必须指定 .FirstOrDefault ,或者迭代您的集合以从中获取项目它,就像这样:
这就是你正在做的:
这是你应该这样做的:
你必须迭代 linqresult 因为当你使用链接查询时,它会返回一个结果集,即使它只有一列。与任何集合一样,您的数据列不适用于整个结果集,仅适用于单个项目。
When you return your resultset AsQueryable, the app is already able to give you intellisense, however in your example, you must specify either .FirstOrDefault if you know your collection will only have a single row, or iterate over your collection to get the items from it, like so:
This is what you're doing:
This is how you should do it:
You must iterate over linqresult because when you query with link, it returns a result set, even if it just has one column. As with any collection, your data columns aren't available on the whole result set, only with individual items.
如果您想要强类型枚举非泛型 IEnumerable(
IEnumerable.GetEnumerator()
而不是IEnumerable.GetEnumerator()
),您可以使用Cast<>() 扩展,就像这样If you want to strongly typed enumerate a non-generic IEnumerable (
IEnumerable.GetEnumerator()
instead ofIEnumerable<T>.GetEnumerator<T>()
) you can use the Cast<>() extension, like so