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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:16:34  来源:igfitidea点击:

Linq To Sql return from function as IQueryable<T>

c#linq-to-sqlgenericsienumerableiqueryable

提问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 myObjectwhen 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 myObjectinstances. 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 SomeClassinstance and sets the properties to the given values. Alternatively you could implement a constructor on the myObjectclass 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;