【问题标题】:Returning LINQ to Entities Query Result as JSON string将 LINQ to Entities 查询结果作为 JSON 字符串返回
【发布时间】:2011-02-04 04:01:31
【问题描述】:

我正在尝试构建一个允许 RESTful 请求将 LINQ to Entities 数据作为 JSON 字符串数据返回的 Web 服务。执行对返回一个特定对象的数据库的调用没有问题:

public Product GetTicket(string s)
        {
            int id = Convert.ToInt32(s);


MWAEntities context = new MWAEntities();
        var ticketEntity = (from p
                            in context.HD_TicketCurrentStatus
                            where p.Ticket_ID == id
                            select p).FirstOrDefault();
        if (ticketEntity != null)
            return TranslateTicketEntityToTicket(ticketEntity);
        else
            throw new Exception("Invalid Ticket ID");

        /**
        Product product = new Product();
        product.TicketId = 1;
        product.TicketDescription = "MyTest";
        product.TicketOperator = "Chad Cross";
        product.TicketStatus = "Work in Progress";
        return product;
        */
    }
    private Product TranslateTicketEntityToTicket(
        HD_TicketCurrentStatus ticketEntity)
    {
        Product ticket = new Product();
        ticket.TicketId = ticketEntity.Ticket_ID;
        ticket.TicketDescription = ticketEntity.F_PrivateMessage;
        ticket.TicketStatus = ticketEntity.L_Status;
        ticket.TicketOperator = ticketEntity.L_Technician;
        return ticket;
    }

使用 curl,我得到 json 数据:

curl http://192.168.210.129:1111/ProductService/ticket/2
{"TicketDescription":"Firewall seems to be blocking her connection to www.rskco.com","TicketId":2,"TicketOperator":"Jeff","TicketStatus":"Completed"}

话虽如此,我不知道如何使用以下查询获取 JSON 对象字符串:

public List<MyTicket> GetMyTickets(string userId)
    {
        MWAEntities context = new MWAEntities();

        /**
         * List of statuses that I consider to be "open"
         * */
        string[] statusOpen = new string[] { "Work in Progress", "Assigned", "Unassigned" };

        /**
         * List of tickets with my userID
         * */
        var tickets = (from p
                       in context.HD_TicketCurrentStatus
                       where statusOpen.Contains(p.L_Status) & p.L_Technician == userId
                       select new MyTicket(p.Ticket_ID, p.Ticket_CrtdUser, p.F_PrivateMessage, p.Ticket_CrtdDate, p.L_Status));

        return ???;
    }

MyTicket 是一个定义如下的类型:

[DataContract]
public class MyTicket
{
    public MyTicket(int ticketId, string TicketCreator, string FirstPrivateMessage, DateTime TicketCreatedDate, string Status)
    {
        this.TicketId = ticketId;
        this.TicketCreator = TicketCreator;
        this.FirstPrivateMessage = FirstPrivateMessage;
        this.TicketCreatedDate = TicketCreatedDate;
        this.Status = Status;
    }
    [DataMember]
    public int TicketId { get; set; }       

    [DataMember]
    public string TicketCreator { get; set; }

    [DataMember]
    public string FirstPrivateMessage { get; set; }

    [DataMember]
    public DateTime TicketCreatedDate { get; set; }

    [DataMember]
    public string Status { get; set; }

    //p.Ticket_CrtdUser, p.Ticket_CrtdDate, p.Ticket_ID, p.F_PrivateMessage
}

我只想获取 JSON 字符串列表作为输出,以便使用 JS 进行解析。我尝试使用 foreach 循环将“var”解析为 MyTicket 对象列表,调用 .ToList()) 等,但无济于事。

我无法更改后端 (SQL 2005/2008),但我正在尝试使用标准 HTML/JS 客户端来使用 .NET 4.0 Web 服务。任何帮助将不胜感激。我花了几天时间搜索和阅读书籍(尤其是在 O'Reilly 的 Safari 网站上),但我还没有找到合理的解决方案:(。

【问题讨论】:

    标签: linq json linq-to-entities


    【解决方案1】:

    使用 Json.NET:http://james.newtonking.com/pages/json-net.aspx

    using Newtonsoft.Json;
    
    var serializer = new JsonSerializer();
    serializer.Serialize(Response.Output, tickets); // per your example
    

    编辑:啊,以上是如果你想自己处理序列化。

    在您的示例中,将方法的返回从 List 更改为 Ticket[] 并执行

    return tickets.ToArray();
    

    【讨论】:

    • 不幸的是,更改返回类型会导致我在几乎所有迭代中得到的结果:运行时错误:“LINQ to Entities 仅支持无参数构造函数和初始化程序”我已经看到了这一点在几个博客中作为 L2E 的严重限制,但我真的不确定我可以使用什么其他层来实现我的目标:构建一个 Web 服务来与一个 SQL 2005/2008 后端接口,以供 RESTful JS/HTML 客户端使用.
    • 您始终可以只返回一个带有 json 的字符串,在这种情况下,我的原始答案对您有用。您的另一种选择可能是更好的做法。不要将您的实体推到电线上。如果您通过服务公开映射到数据库的实体,那么您将服务与数据库紧密耦合。如果您的数据库模型发生更改,您的所有客户端都会中断。创建一个 POCO 层,将 db 对象转换为服务对象,然后您将解决这两个问题(L2E 错误和紧耦合架构)。更多的工作和更多的代码,但更好的长期性。
    • 谢谢肖恩。更多的研究是。我想以正确的方式去做,而不仅仅是可能的工作方式。
    【解决方案2】:

    我想补充一点,我最终得到了解决这个问题的帮助。即使我使用的是实体框架,我也没有使用业务实体。这可能不是一个明智的决定,但我越来越对 Linq2SQL 和 Linq2EF 感到困惑。这是使上述工作的代码:

    public List<MyTicket> GetMyTickets(string userId)
        {
            MWAEntities context = new MWAEntities();
    
            /**
             * List of statuses that I consider to be "open"
             * */
            string[] statusOpen = new string[] { "Work in Progress", "Created"};
    
            var tickets = (from p
                           in context.HD_TicketCurrentStatus
                           where statusOpen.Contains(p.L_Status) & p.L_Technician == userId
                           select new MyTicket{
                               TicketId = p.Ticket_ID,
                               TicketCreatedDate = p.Ticket_CrtdDate,
                               FirstPrivateMessage = p.F_PrivateMessage,
                               Status = p.L_Status,
                               TicketCreator = p.Ticket_CrtdUser
                           });
            return tickets.ToList();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多