ASP.NET MVC + Dynamics NAV odata Web服务 - 如何访问相关模型?

时间:2015-02-03 13:33:05

标签: asp.net-mvc web-services odata microsoft-dynamics

我正在使用Dynamics NAV Odata网络服务构建一个asp.net mvc应用程序。 Evertyhing工作正常,我使用Linq查询为服务订单创建了一个控制器。然后我进入下一步:访问相关模型,我就陷入困境。

让我们以第5900页 - 服务订单和第5903页 - 服务项目行:

为例

获取服务订单或任何其他单一模型非常有用:

var query = from c in nav.ServiceOrder 
            select c;

但是访问相关数据失败了:

var query = nav.ServiceOrder
            .Expand(x => x.ServiceOrderServItemLines)
            .Where(x => x.No == "SO000008");

我可以使用以下URL访问ServiceOrderServItemLines:

/ DynamicsNAV71 / OData / Company('公司')/ ServiceOrder(Document_Type =' Order',No =' SO000008')/ ServiceOrderServItemLines

但是使用expand似乎不起作用。

我不确定问题是什么。模型之间没有关系吗?

如果是这样,我可以通过关系添加自己的模型,并将它们连接到odata服务吗?

或者只是扩展而不是服务支持?

非常感谢任何意见。

2 个答案:

答案 0 :(得分:0)

您的serviceOrder似乎有两个键。一个是Document_Type,一个是No.所以请尝试

var query = nav.ServiceOrder
    .Expand(x => x.ServiceOrderServItemLines)
    .Where(x => x.Document_Type == "Order" && x.No == "SO000008");

如果它无法解决您的问题,请提供扩展查询发送的网址?

答案 1 :(得分:0)

因此,在打了我的脑袋一段时间后,我想我有一个答案。我会在这里发布我的发现,并希望它将来会为某些人带来一些麻烦。

Dynamics NAV(2013 R2)在标题和列表项之间具有关系,如下所述: http://blogs.msdn.com/b/freddyk/archive/2009/05/28/handling-sales-orders-from-page-based-web-services-in-nav-2009sp1-and-rtm.aspx

在我的情况下,我想为服务订单创建和访问服务项目行。

使用SOAP创建服务订单(Service Header表)和Service Item Lines可以这样做:

    static void Main(string[] args)
    {
        ServiceOrder_Binding ctx = new ServiceOrder_Binding();
        ctx.UseDefaultCredentials = true;

        //Create a new Service Order
        ServiceOrder so = NewSo(ctx);

        //Add a couple of Service Item Lines to the Service Order
        for (int i = 0; i < 5; i++)
            NewSil(ctx, so.No);
    }

    private static ServiceOrder NewSo(ServiceOrder_Binding ctx)
    {
        ServiceOrder so = new ServiceOrder();
        so.Customer_No = "50000";
        so.Description = "New Service Order";
        ctx.Create(ref so);
        return so;
    }

    private static void NewSil(ServiceOrder_Binding ctx, string documentNo)
    {
        ServiceOrder so = ctx.Read(documentNo);
        List<Service_Order_Line> SilList = so.ServItemLines.ToList();
        Service_Order_Line Sil = new Service_Order_Line();
        Sil.ServiceItemNo = "20";
        Sil.Description = "New Service Item Line";
        SilList.Add(Sil);
        so.ServItemLines = SilList.ToArray();
        ctx.Update(ref so);
    }

使用Odata读取服务订单(服务标题表)和服务项目行可以这样做:

    static void Main(string[] args)
    {
        NAV ctx = new NAV(new Uri("http://localhost:7048/DynamicsNAV71/OData/Company('CRONUS Sverige AB')"));
        ctx.UseDefaultCredentials = true;

        //Eager loading - DOES NOT WORK!
        var so = from s in ctx.ServiceOrder.Expand("ServiceOrderServItemLines")
                 where s.No == "SO000016"
                 select s;

        //Lazy loading - WORKS!
        var so2 = from s in ctx.ServiceOrder
                 where s.No == "SO000016"
                 select s;

        ctx.LoadProperty(so2.First(), "ServiceOrderServItemLines");
    }

请注意,延迟加载有效,但急切加载却没有。

对于其他相关数据,例如服务项目行的服务项目,似乎没有任何关系。如果我找到其他内容,我会返回更新,但我现在最终要做的是在ViewBag中传递相关项目,如下所示:

在Controller Action中:

    var service_items = from s in ctx.ServiceItemList
                        where s.Customer_No.Equals(customerNo)
                        select s;

    var serviceItemList = service_items.ToList();

    ViewBag.serviceItemList = new SelectList(serviceItemList, "No", "Description");

在视图中:

    @Html.DropDownListFor(model => model.Service_Item_No, (IEnumerable<SelectListItem>)ViewBag.serviceItemList)

希望这有助于喜欢我的人不熟悉使用Dynamics NAV和Web服务:)。