【问题标题】:Calling a query from RIA Services with entities that have children created by other methods使用具有由其他方法创建的子对象的实体从 RIA 服务调用查询
【发布时间】:2012-08-07 18:34:04
【问题描述】:

我的这段代码不起作用,因为 Entity Framework 无法识别 CreateItemDC 方法。 CreateItemDC 是一种模块化私有方法,它为给定的 Item 实体创建数据协定。每当我需要返回项目数据合同时,我在整个服务中都使用CreateItemDC,但我不能在这里使用它。我可以将ProjectItems 的序列实现为数组或可枚举,因为我必须对数据库中的所有ProjectItem 实体执行此操作,因为查询条件是在客户端上指定的,而我在这里无权访问它。我在这里有更好的选择吗?似乎 RIA 服务不值得麻烦。我真的希望我在这个项目中使用了普通的 WCF。

    [Query]
    public IQueryable<ProjectItemDC> GetProjectItems()
    {
        return from projectItem in ObjectContext.ProjectItems
               select new ProjectItemDC
               {
                   ID = projectItem.ID,
                   LibraryItem = CreateItemDC(projectItem.LibraryItem),
                   LibraryItemID = projectItem.LibraryItemID,
                   ProjectID = projectItem.ProjectID,
                   Quantity = projectItem.Quantity,
                   Width = projectItem.Width,
                   Height = projectItem.Height,
                   Depth = projectItem.Depth,
                   SheetMaterialID = projectItem.SheetMaterialID,
                   BandingMaterialID = projectItem.BandingMaterialID,
                   MaterialVolume = projectItem.MaterialVolume,
                   MaterialWeight = projectItem.MaterialWeight
               };
    }

附:不过,我确实喜欢 LINQ 和 E.F.。 :)

【问题讨论】:

    标签: linq entity-framework wcf-ria-services


    【解决方案1】:

    好吧,如果你想使用普通的 WCF,你可以,没问题,只需将代码更改为

    [Query(IsComposable=false)]
    public IEnumerable<ProjectItemDC> GetProjectItems(string myParm1, string myParm2) 
        { 
            return from projectItem in ObjectContext.ProjectItems 
                   select new ProjectItemDC 
                   { 
                       ID = projectItem.ID, 
                       LibraryItem = CreateItemDC(projectItem.LibraryItem), 
                       LibraryItemID = projectItem.LibraryItemID, 
                       ProjectID = projectItem.ProjectID, 
                       Quantity = projectItem.Quantity, 
                       Width = projectItem.Width, 
                       Height = projectItem.Height, 
                       Depth = projectItem.Depth, 
                       SheetMaterialID = projectItem.SheetMaterialID, 
                       BandingMaterialID = projectItem.BandingMaterialID, 
                       MaterialVolume = projectItem.MaterialVolume, 
                       MaterialWeight = projectItem.MaterialWeight 
                   }.ToArray(); 
        } 
    

    编写您自己的过滤/排序逻辑,您就完成了。 是的,您已经失去了 WCF Ria 服务动态查询功能,但这几乎就是您使用普通旧 WCF 所获得的功能,不是吗?

    如果您需要 WCF Ria 动态排序/过滤/分组,则必须采取一些额外的步骤,包括访问 WCF Ria 服务为您创建的表达式。

    HTH

    【讨论】:

    • 如何获得表达式?
    • 覆盖您的 DomainService 类的 Query 方法,如果客户端已经指定了一个表达式,则参数 queryDescription 的属性 Query 是 valorized。所以你可以抓住 queryDescription.Query.Expression
    【解决方案2】:

    您可以针对 ObjectContext.ProjectItems 调用 ToArray() 以强制 EF 加载所有项目,但是,您的查询将不再可在客户端上组合。

    [Query]
    public IQueryable<ProjectItemDC> GetProjectItems()
    {
        return from projectItem in ObjectContext.ProjectItems.ToArray()
               select new ProjectItemDC
               {
                   ID = projectItem.ID,
                   LibraryItem = CreateItemDC(projectItem.LibraryItem),
                   LibraryItemID = projectItem.LibraryItemID,
                   ProjectID = projectItem.ProjectID,
                   Quantity = projectItem.Quantity,
                   Width = projectItem.Width,
                   Height = projectItem.Height,
                   Depth = projectItem.Depth,
                   SheetMaterialID = projectItem.SheetMaterialID,
                   BandingMaterialID = projectItem.BandingMaterialID,
                   MaterialVolume = projectItem.MaterialVolume,
                   MaterialWeight = projectItem.MaterialWeight
               };
    }
    

    编辑:

    正如您在评论中提到的,它一次将所有数据从数据库中取出,这并不理想。为了使用您的私有方法创建LibraryItem,您不能在客户端上编写查询。相反,您应该在查询方法中进行过滤,然后创建数组。

    [Query]
    public IQueryable<ProjectItemDC> GetProjectItems(int id, string filter, object blah)
    {
        var projectItems = ObjectContext.ProjectItems.Where(...).ToArray();
        return projectItems.Select(projectItem => new ProjectItemDC{...};
    }
    

    【讨论】:

    • 这将在内存中为数据库中的每个ProjectItem 实体创建一个数组。这不是一个选择。
    • 除非您在客户端上编写查询,否则您已经在提取所有数据。
    • 我最终做了什么。我的下一个项目将使用 WCF。我想如果你做直接的 CRUD RIA 服务是有道理的,但我在去年左右碰到了很多砖墙,所以我自己已经完成了它。我确实喜欢在客户端上编写查询,但其他方面的限制太多了。
    • WCF RIA 非常固执己见。我同意 WCF 是正确的解决方案,当您想要或需要实施的方式冒犯 WCF RIA 的意见时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多