如何返回多个类作为IQueryable<T>?

4
使用Linq,我想返回一个包含客户和他们的发票的对象。
我知道从方法中返回单个类型:
public IQueryable<customers> GetCustomers()
{
    return from c in customers
           select c;
}

但我在处理多个对象时遇到了一些问题:

public IQueryable<???> GetCustomersWithInvoices()
{
    return from c in customers
           from inv in c.invoices
           select new {c, ci}  // or I may specify columns, but rather not.
}

我觉得我的方法可能不对。目标是从控制器调用这些对象并将它们传递给视图,可以直接传递或使用formViewModel类。


可能是返回匿名类型?的重复问题。 - nawfal
3个回答

2
在第二种情况下,您正在创建一个具有方法作用域的匿名类型。要将匿名类型传递到方法边界之外,您需要将返回类型更改为对象。但这会破坏匿名类型的目的(因为您失去了它提供的强类型),需要使用反射来访问所述类型的属性及其值。
如果您想将此结构保留为返回类型,则应创建一个类或结构,其中包含属性以保存客户和发票值。

有道理,现在取个名字吧... :) - Brettski
我创建了一个类,它被返回为list<MyClass>。虽然这样做是可以的,但我并不喜欢这种方式,我更想直接返回一个对象,并使用customer.invoices.invoiceid等方式来获取数据。这种方法看起来更简洁清晰。 - Brettski
你应该能够以这种方式完成它。当打开你的 DataContext 以在加载客户对象时包括发票时,你只需要指定一个 DataLoadOptions。请参阅 http://msdn.microsoft.com/zh-cn/library/system.data.linq.dataloadoptions.loadwith.aspx。 - Simon Fox

1

你不能从函数中返回匿名类型,他们是严格的“内联”类。如果你想要在函数中封装它们,你需要创建一个具体的类型来保存你的成员。

正如你提到的那样,使用视图模型是一个很好的放置它们的地方。

这里 是关于匿名类型的scottgu文章。从文章的结论中可以看出:

匿名类型是一种方便的语言特性,使开发人员能够在代码中简洁地定义内联CLR类型,而无需显式提供类型的正式类声明。虽然它们可以用于许多场景,但在使用LINQ查询和转换/形状数据时特别有用。

该页面的评论线程中有一些很好的讨论。


从技术上讲,你可以将函数的返回类型设置为 objectIEnumerable<object>,它们都能正常工作。但是,你能否对结果进行有用的操作还有待商榷。 - Joel Mueller
这正是我正在苦苦挣扎的问题。我只想从数据库中查询客户和发票,将它们发送并迭代到网页上;这应该不复杂。 - Brettski

0

如果你真的想要,你可以这样做,但是这样做相当笨拙。

public IQueryable<T> GetCustomersWithInvoices(T exampleObject)
{
return from c in customers
from inv in c.invoices
select new {c, ci} // 或者我可以指定列,但最好不要。
}

var exampleObject = new {
Customer c = new Customer(),
Invoice i = new Invoice()
};

var returnedObjectOfAnonymousType = GetCustomersWithInvoices(exampleObject);

通过这种方式,您可以利用类型推断使您的方法返回匿名类型。您必须使用传递示例对象的丑陋方法才能使其正常工作。我并不真正建议您这样做,但我相信这是唯一的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接