5

好的,我已经设法使以下工作

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),其中包含原语ticket_id、title、care_of_email 和filename。哪些是我在 linq 语句中返回的项目。

我将我的声明修改为

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

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;
}
4

4 回答 4

14

你的意思是:

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

(请注意,我稍微调整了名称以更符合 C# 习惯)

这是一个“对象初始化器”,它创建一个新的MyObject(每条记录)并从源数据中分配属性。你所拥有的是一个“匿名类型”初始化程序,这不一样。请注意,如果您有一个非默认构造函数,您还可以使用类似的东西:

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

它使用指定的构造函数,从源数据传入提供的值。

这将是IQueryable<MyObject>;你不需要打电话.AsQueryable()。请注意,您的函数返回类型化的形式 ( IQueryable<MyObject>) 比返回非类型化的形式更好IQueryable

于 2009-01-20T11:06:41.113 回答
8

此行在语法上不正确:

return ticketDetails.AsQueryable()<myObject>;

并且应该阅读

return ticketDetails.AsQueryable<myObject>();

此外,您正在使用创建匿名对象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
        };

}

new SomeClass() { Property = value, ...语法创建一个SomeClass实例并将属性设置为给定值。或者,您可以在该类上实现一个构造函数,myObject并在 linq 语句中使用select new myObject(...).

于 2009-01-20T11:22:09.587 回答
2

正如 Marc 所说,您没有构建myObject查询运行时间的实例。但另外,您不需要将其强制转换为IQueryable<T>,LINQ 选择语句将返回一个IQueryable<T>除非显式强制转换为IEnumerable<T>.

此外,在您尝试访问返回的数据之前,请注意您的 DataContext 尚未被处理掉。但是我注意到您的上下文不是在方法中构造的,请注意不要将 DataContext 维护太久,它是一个工作单元对象,并不意味着长时间保持打开状态。

于 2009-01-20T11:14:23.783 回答
1

绅士们,只要你只返回一张桌子,这一切都是有道理的,但是如果有两个或更多要返回呢?

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;        
于 2012-03-18T20:11:05.033 回答