简体   繁体   English

Linq To Sql从函数返回为IQueryable <T>

[英]Linq To Sql return from function as IQueryable<T>

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. 我继续创建我自己的类(myObject),其中包含基元ticket_id,title,care_of_email和filename。 Which are the items I am returning in my linq statement. 我在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;
}

You mean: 你的意思是:

select new MyObject { TicketId = tickets.ticket_id,
     Title = tickets.title, ...};

(note I tweaked the names slightly to be more C#-idiomatic) (注意我稍微调整了一些名字,以便更加C#-idiomatic)

This is an "object initializer" that creates a new MyObject (per record) and assigns the properties from the source data. 这是一个“对象初始值设定项”,它创建一个新的MyObject (每个记录)并从源数据中分配属性。 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: 请注意,如果您有非默认构造函数,您还可以使用以下内容:

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> ; 这将是IQueryable<MyObject> ; you don't need to call .AsQueryable() . 你不需要调用.AsQueryable() Note it would be better for your function to return the typed form ( IQueryable<MyObject> ) than the untyped IQueryable . 请注意,函数返回类型化表单( IQueryable<MyObject> )比使用无类型IQueryable更好。

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. 此外,您正在使用select new {创建匿名对象,但您想要创建myObject实例。 A correct implementation would look like this: 正确的实现将如下所示:

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. new SomeClass() { Property = value, ...语法创建一个SomeClass实例并将属性设置为给定的值。 Alternatively you could implement a constructor on the myObject class and call it in the linq statement with select new myObject(...) . 或者,您可以在myObject类上实现构造函数,并使用select new myObject(...)在linq语句中调用它。

As Marc stated you're not constructing instances of myObject when your query is run. 正如Marc所说,在运行查询时,你并没有构造myObject实例。 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> . 但另外你不需要将它IQueryable<T>转换为IQueryable<T> ,LINQ select语句将返回IQueryable<T>除非明确地强制转换为IEnumerable<T>

Also, be careful that your DataContext hasn't been disposed of before you try and access the data being returned. 另外,在尝试访问返回的数据之前,请注意没有丢弃DataContext。 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,它是一个工作单元对象,并不打算长时间保持打开状态。

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??? Gents,只要您只返回单个表,这一切都有意义,但是如果有两个或更多要返回怎么办?

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;        

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

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