LinQ和WCF服务操作

时间:2012-07-26 10:14:05

标签: wcf linq entity-framework

我在让一些LinQ在WCF服务操作中工作时遇到问题:

[WebGet]
public IQueryable<StockItem> AllStockableItems(int LocationAddressId)
    {
    StockEntities svc = this.CurrentDataSource;

    //get all the stock at a location
    var StockAtLocation = from s in svc.Stock
                          where s.Location == Location
                          select s;

    //weave it into the list of all stockable items
    var StockableItems = from si in svc.StockableItems
                         join s in StockAtLocation on si.ItemId equals s.ItemId into tmp
                         select si <and somehow expand> si.Stock;

    return StockableItems;
    }

问题是,我不知道如何在返回的数据中扩展库存?

以下网址:

... my.svc / AllStockableItems LocationAddressId = 3&安培; $扩大=库存

将扩大所有地点的库存,而不仅仅是所需的位置。这是可能的,还是我最好的选择,从Silverlight客户端发出两个单独的请求,并加入客户端?

非常感谢任何帮助。

是的,示例数据,抱歉没有第一次出现: 示例库存数据:

ItemId    Location   Quantity
   1         1           4
   1         2           3
   1         3           2
   2         2           6
   3         3           0
   7         1           3
   7         2           0

示例stockableItems数据

 ItemId   <other columns>..
   1
   2
   3
   4
   5
   6
   7
   8

假设locationAddressId参数= 2,我正在尝试返回服务操作(不是按字面意思,而是在Atom / Pub中等效):

StockableItem  { ItemId :1 
                 Stock { 
                     entry { 
                           Stock {LocationId : 2, Qty :4} 
                           } 
                       } 
               }
StockableItem  { ItemId :2 }
StockableItem  { ItemId :3 }
StockableItem  { ItemId :4 }
StockableItem  { ItemId :5 }
StockableItem  { ItemId :6 }
StockableItem  { ItemId :7 
             Stock { 
                     entry { 
                           Stock {LocationId : 2, Qty :0} 
                           } 
                   } 
               }
StockableItem  { ItemId :8 }

谢谢。

[更新2]

好的,我尝试了几件事;首先我放弃了这个:

var StockableItems = from si in svc.AllStockableItems
                     join s in svc.Stock on si.ItemId equals s.ItemId
                     where s.Location == Location
                     select  new StockableItem
                           {
                           ItemId = s.ItemId,
                           Stock = new EntityCollection<Stock>
                                    {
                                    new Stock()
                                        {
                                        Location = s.Location,
                                        Quantity= s.Quantity
                                        }
                                    }
                           };

哪位给了我:

The entity or complex type '...' cannot be constructed in a LINQ to Entities query

让我来到这里:

The entity cannot be constructed in a LINQ to Entities query

这导致我重新编写查询:

var StockableItems = svc.AllStockableItems
                    .Join(svc.Stock, si => si.ItemId, s => s.ItemId, (si, s) => si)
                    .ToList()
                    .Select(si => new StockableItem
                       {
                       ItemId = si.ItemId,
                       Stock = new EntityCollection<Stock>
                           {
                           new Stock()
                                {
                                Location = si.Stock.First().Location,
                                Quantity= si.Stock.First().Quantity
                                }
                           }
                       })
                       .AsQueryable();

返回所有StockableItems,但有点令人沮丧的是,不包括任何Stock。我是否只是在最后一个查询中做了一个嘘声?我怀疑我对Stock实体的内部投影是不正确的?

再次感谢

1 个答案:

答案 0 :(得分:0)

我认为你正在寻找这样的东西:

var StockableItems = from si in svc.StockableItems
    join s in StockAtLocation on si.ItemId equals s.ItemId
    select new
    {
        StockableItem = si,
        Stock = s
    };

您可以在select子句中选择如何投影输出。您可以选择整个对象,如上所述,也可以选择对象中的字段。例如:

    select new
    {
        ItemId = si.ItemId,
        Stock = s,
        Qty = s.Quantity
    };

此外,您可能需要考虑将两个查询合并为一个查询:

var StockableItems = from si in svc.StockableItems
    join s in svc.Stock on si.ItemId equals s.ItemId
    where s.Location == Location
    select new
    {
        StockableItem = si,
        Stock = s
    };

现在再举一个例子,向您展示与您的示例输出非常接近的内容:

var StockableItems = from si in svc.StockableItems
    join s in svc.Stock on si.ItemId equals s.ItemId
    where s.Location == Location
    select new
    {
        StockableItem = new
        {
            ItemId = s.ItemId,
            Stock = new
            {
                LocationId = s.Location,
                Qty = s.Quantity
            }
        }
    };

更新

我对您修改后的查询进行了一些调整,该查询使用Join创建传递到查询其余部分的数据。我还将你的Where子句放回去(如果你想在那里使用它)来过滤位置。我也把ToList()带出那里因为我不确定是否有必要。

var StockableItems = svc.AllStockableItems 
                .Join(svc.Stock, si => si.ItemId, s => s.ItemId, 
                      (si, s) => new 
                      { 
                          ItemId = si.ItemId, 
                          Location = s.Location, 
                          Quantity = s.Quantity
                      }) 
                .Where(x => x.Location == Location)
                //.ToList() 
                .Select(x => new StockableItem 
                   { 
                   ItemId = x.ItemId, 
                   Stock = new EntityCollection<Stock> 
                       { 
                       new Stock() 
                            { 
                            Location = x.Location, 
                            Quantity= x.Quantity 
                            } 
                       } 
                   }) 
                   .AsQueryable();