1

我有 DbContext 子类

ReportingContext : DbContext

当我在做简单的 CRUD 时,我创建了一个 WCF 数据服务来公开我的 DbSet ...

public class ReportService : DataService<ReportingContext>

我已经能够直接使用 ReportingContext 来进行“表拆分”。基本上使用 2 个实体(ReportLayout 和 ReportLayoutData),它们都使用一个表。我能够使用 fluent API 进行配置。在单元测试中一切正常,因为我能够返回 ReportLayouts 并且仅在访问它们时加载 ReportLayoutData。

当我尝试通过 WCF 数据服务、OData 版本 5.6 执行此操作时,我的问题开始了 - 使用 DataServiceContext 类。返回 ReportLayouts 工作正常,但到目前为止还无法尝试延迟加载相关数据。我尝试了不同的东西:

  • 当我直接调试服务并检查生成的 sql - 2 个单独的查询作为单元测试时,通过服务方法调用 Include 确实有效。但是,在浏览器中查看时,该服务根本没有在其返回的属性中包含 ReportLayoutData 属性,并且我收到了与缺少属性相关的客户端错误。

    [WebGet]
    public IQueryable<ReportLayout> GetReportsByID(string ids)
    {
        var ints = GetInts(ids);
        return  CurrentDataSource.Reports.Include("LayoutData").Where(x =>  ints.Contains(x.ReportLayoutID)).AsQueryable();
    }
    
    private static int[] GetInts(string ids)
    {
        return ids.Split(",".ToCharArray()).Select(x => Convert.ToInt32(x)).ToArray();
    }
    
  • 我尝试使用 DataServiceContext.Expand - $expand - 当我尝试略有不同的参数时,失败并出现各种错误

  • 我尝试调用Execute,各种问题

  • 我将 ReportLayoutData 属性转换为 IQueryable,即使它是 1-1 关系,现在它说 ReportLayoutData 在运行以前运行良好的 EF 特定单元测试时不是 ReportLayout 的属性。

我的问题:是否可以通过 WCF 数据服务以这种方式进行延迟加载,还是应该只公开 2 个集合并将结果解析为客户端上的单个对象?如果可能的话,我只想看看基本模式——几个相关的实体、流畅的 API 声明和 DataService 代码。谢谢你的帮助。

编辑

我目前正受到错误的困扰:

类型为“ReportLayout”的名称为“LayoutData”的属性具有“Structural”类型,但应为“Navigation”类型。

虽然在浏览器中检索数据没有问题:ReportService.svc/Reports()?$expand=LayoutData

部分堆栈跟踪:

Microsoft.Data.OData.ReaderValidationUtils.ValidateNavigationPropertyDefined(String propertyName, IEdmEntityType owningEntityType, ODataMessageReaderSettings messageReaderSettings) 在 Microsoft.Data.OData.Atom.ODataAtomEntryAndFeedDeserializer.TryReadNavigationLinkInEntry(IODataAtomReaderEntryState entryState, String linkRelation, String linkHRef)

通过不通过服务公开 2 个 dbSet,我能够消除上述错误。会考虑一个服务操作来从 EF 返回我需要的东西,可惜它不是那么优雅。

4

1 回答 1

0

最后,我的解决方案是拆分表,以便创建一个作为 ICollection 公开的导航属性

结果,我能够实现诸如Reports/ReportService.svc/Reports(1) $expand=LayoutData 之类的查询 (AddQueryOption("$expand", "LayoutData") 并编写了一个服务方法来为倍数执行此操作。

    [WebGet]
    public IQueryable<ReportLayout> GetReportsByID(string ids)

我只通过该服务公开了一个 Dbset - 无法直接访问子级。

可以使用 DataServiceContext 方法实现对依赖实体的客户端更新:

AddObject, AddLink
AttachTo, UpdateObject, AttachLink //UpdateObject on the child ensures the entity state changes to modified (see DataServiceContext.Entites collection).

回想起来,我可能不需要拆分桌子,但没有时间玩这个。

于 2013-09-30T15:02:06.570 回答