关于c#:Linq To Sql从函数返回IQueryable< T>

Linq To Sql return from function as IQueryable<T>

好吧,我已经设法让下面的工作

1
2
3
4
5
6
7
8
9
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();
}

我接着创建了自己的类(myObject),其中包含原语票据ID、标题、注意事项电子邮件和文件名。这是我在LINQ声明中返回的项目。

我把我的陈述修改成

1
2
3
4
5
6
7
8
9
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>;
}

我认为这会使它在使用泛型时安全,但我得到了错误"无法将方法组"asqueryable"转换为非委托类型"system.linq.iqueryable"。"是否要调用该方法?"

我想做的事情是否可能?

MyObject类是否需要实现IEnumerable或IQueryable?

或者最好从Linq结果集构造对象MyObject,然后从对象MyObject函数返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}


你的意思是:

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

(注:我的名字是更tweaked稍大的C - idiomatic #)

这是一个"面向对象initializer",creates MyObject(每一新记录)和assigns从源数据的属性。你有什么initializer"是一个匿名类型",这不是相同的。注意,如果你有一个非安装默认的构造,也你可以使用一些如:

1
select new MyObject(tickets.ticket_id, tickets.title);

其中使用的规定的构造,通过在提供给从源数据的价值。

这将是IQueryable然后;你不需要打电话.AsQueryable()。注意它会更好地为你的函数形式(IQueryable归来的强类型的untyped IQueryable)煤。


这条线是不正确的:syntactically

1
return ticketDetails.AsQueryable()<myObject>;

和应该读

1
return ticketDetails.AsQueryable<myObject>();

同时,你创造的select new {与匿名对象,但你想要的MyObject的情况下创造的。这会看起来像一个correct实施:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
        };

}

一个语法的new SomeClass() { Property = value, ...creates SomeClassinstance集的给定的属性和价值。另外,你可以在一个类的MyObjectimplement构造和调用它在linq与select new myObject(...)项声明。


作为马克指出你不当的情况下构建的MyObject查询是颤抖的。但此外你不需要安全IQueryable投它,一个安全的查询将返回linq statment IQueryable除非explicity IEnumerable投大的安全。

同时,要仔细,你的datacontext hasn已在你的disposed的尝试和访问的数据被返回。但我注意到你的背景是不在方法的建成,是仔细的,你不是一个datacontext为维持太长,这是一个面向对象的工作单位和不打算长时间为periods保持开放。


gents, 这一切的意义是只要你只returning单表,但如果有两个或更多的大的返回???

1
2
3
4
5
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;