C# Linq To Sql 从函数返回为 IQueryable<T>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/460831/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Linq To Sql return from function as IQueryable<T>
提问by
Ok, I have managed to get the following working
好的,我已经设法使以下工作
public IQueryable getTicketInformation(int ticketID)
{
var ticketDetails = from tickets in _context.tickets
join file in _context.file_objects on tickets.ticket_id equals file.source_id
where tickets.ticket_id == ticketID
select new { tickets.ticket_id, tickets.title, tickets.care_of_email, file.filename };
return ticketDetails.AsQueryable();
}
I went ahead and created my own class (myObject) containing the primitives ticket_id, title, care_of_email and filename. Which are the items I am returning in my linq statement.
我继续创建了自己的类 (myObject),其中包含原语 ticket_id、title、care_of_email 和文件名。哪些是我在 linq 语句中返回的项目。
I modified my statement to be
我将我的声明修改为
public IQueryable<myObject> getTicketInformation(int ticketID)
{
var ticketDetails = from tickets in _context.tickets
join file in _context.file_objects on tickets.ticket_id equals file.source_id
where tickets.ticket_id == ticketID
select new { tickets.ticket_id, tickets.title, tickets.care_of_email, file.filename };
return ticketDetails.AsQueryable()<myObject>;
}
thinking that this would make it type safe with generics, but I get the error "Cannot convert method group 'AsQueryable' to non-delegate type 'System.Linq.IQueryable'. Did you intend to invoke the method?"
认为这会使泛型类型安全,但我收到错误“无法将方法组‘AsQueryable’转换为非委托类型‘System.Linq.IQueryable’。您是否打算调用该方法?”
Is what I am trying to do even possible?
我正在尝试做的甚至可能吗?
Does the myObject class need to implement IEnumerable or IQueryable?
myObject 类是否需要实现 IEnumerable 或 IQueryable?
Or is it best to construct the object MyObject from the linq resultset and then just return from the function the object MyObject
或者最好从linq结果集构造对象MyObject,然后从函数返回对象MyObject
public myObject getTicketInformation(int ticketID)
{
....linq statement....
myObject o = null;
foreach (obj in linqstatemt)
{
o = new myObject();
o.ticket_id = obj.ticket_id
.......
}
return o;
}
回答by Marc Gravell
You mean:
你的意思是:
select new MyObject { TicketId = tickets.ticket_id,
Title = tickets.title, ...};
(note I tweaked the names slightly to be more C#-idiomatic)
(请注意,我稍微调整了名称以使其更符合 C# 惯用语)
This is an "object initializer" that creates a new MyObject
(per record) and assigns the properties from the source data. What you had was an "anonymous type" initializer, which isn't the same. Note that if you have a non-default constructor, you could also use something like:
这是一个“对象初始值设定项”,它创建一个新的MyObject
(每条记录)并从源数据分配属性。您拥有的是一个“匿名类型”初始化程序,它不一样。请注意,如果您有一个非默认构造函数,您还可以使用以下内容:
select new MyObject(tickets.ticket_id, tickets.title);
which uses the specified constructor, passing in the supplied values from the source data.
它使用指定的构造函数,从源数据传入提供的值。
This will then be IQueryable<MyObject>
; you don't need to call .AsQueryable()
. Note it would be better for your function to return the typed form (IQueryable<MyObject>
) than the untyped IQueryable
.
这将是IQueryable<MyObject>
; 你不需要打电话.AsQueryable()
。请注意,您的函数返回类型化形式 ( IQueryable<MyObject>
) 比非类型化形式更好IQueryable
。
回答by Aaron Powell
As Marc stated you're not constructing instances of myObject
when your query is run. But additionally you don't need to cast it to an IQueryable<T>
, a LINQ select statment will return an IQueryable<T>
unless explicity cast to an IEnumerable<T>
.
正如 Marc 所说,您没有构建myObject
查询何时运行的实例。但另外你不需要将它转换为IQueryable<T>
,IQueryable<T>
除非明确地转换为,否则LINQ 选择语句将返回IEnumerable<T>
。
Also, be careful that your DataContext hasn't been disposed of before you try and access the data being returned. But I noticed your context is not constructed in the method, be careful that you're not maintaining a DataContext for too long, it's a unit-of-work object and not meant to be kept open for long periods of time.
此外,在尝试访问返回的数据之前,请注意您的 DataContext 尚未被处理。但是我注意到您的上下文不是在方法中构造的,请注意不要将 DataContext 维护太久,它是一个工作单元对象,不打算长时间保持打开状态。
回答by David Schmitt
This line is syntactically incorrect:
此行在语法上不正确:
return ticketDetails.AsQueryable()<myObject>;
and should read
应该阅读
return ticketDetails.AsQueryable<myObject>();
Also, you're creating anonymous objects with the select new {
, but you want to create myObject
instances. A correct implementation would look like this:
此外,您正在使用 来创建匿名对象select new {
,但您想创建myObject
实例。正确的实现如下所示:
public IQueryable<myObject> getTicketInformation(int ticketID)
{
return from tickets in _context.tickets
join file in _context.file_objects on tickets.ticket_id equals file.source_id
where tickets.ticket_id == ticketID
select new myObject() {
ticket_id = tickets.ticket_id,
title = tickets.title,
care_of_email = tickets.care_of_email,
filename = file.filename
};
}
The new SomeClass() { Property = value, ...
syntax creates a SomeClass
instance and sets the properties to the given values. Alternatively you could implement a constructor on the myObject
class and call it in the linq statement with select new myObject(...)
.
该new SomeClass() { Property = value, ...
语法创建一个SomeClass
实例并将属性设置为给定的值。或者,您可以在myObject
类上实现一个构造函数,并在 linq 语句中使用select new myObject(...)
.
回答by Jake
Gents, It all makes sense as long as you're only returning single table, but what if there's two or more to be returned???
绅士们,只要您只返回单桌,这一切都有意义,但是如果要返回两张或更多呢????
RPDTDataContext smdt = new RPDTDataContext();
var projectedUsers = smdt.SM_Users.Join(
smdt.SM_CTSGroups, u => u.CtsGroupID, c => c.id,
(u, c) => new { CTSGroup = c.Name, UserName = u.Name, u.EmpID, u.Email });
return projectedUsers;