【发布时间】:2013-09-25 11:43:10
【问题描述】:
我有 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 关系,现在它说在运行以前运行良好的 EF 特定单元测试时 ReportLayoutData 不是 ReportLayout 的属性。
我的问题:是否可以通过 WCF 数据服务以这种方式进行延迟加载,或者我应该只公开 2 个集合并将结果解析为客户端上的单个对象?如果可能的话,我只想看看基本模式——几个相关的实体、流畅的 API 声明和 DataService 代码。感谢您的帮助。
编辑
我目前正被错误困扰:
类型为“ReportLayout”的名为“LayoutData”的属性具有“结构”类型,但应为“导航”类型。
虽然在浏览器中检索数据没有问题: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 返回我需要的东西,可惜它不是那么优雅。
【问题讨论】:
-
首先,没有现成的实现延迟加载的方法。这当然是可能的。但是,我强烈反对它。使用 OData 的往返行程通常约为几百毫秒。延迟加载本质上是一种同步模式。在典型的应用程序中,用户会注意到几百毫秒的无响应。如果我们是紧密循环,请完全忘记 UX。您可以查看
DataServiceContext.LoadProperty,但我建议您尽可能使用异步调用。 -
@Aron 谢谢你 - 我确实尝试过 LoadProperty,如果我没记错的话,它给了我一条错误消息,说它只适用于集合。我当时的 ReportLayout 当时只公开了一个 virtual ReportLayoutData 对象。我可以再试一次,如果只是为了看到它工作的满足感。我认为您对 UX 的看法是正确的,但没有看到问题,因为它只是一个请求,并且此调用可以异步进行。
-
@Aron 真痛苦,如果我将 ReportLayout.LayoutData 设为集合,我在尝试实例化服务时会收到缺少属性异常。如果我尝试将 LoadProperty 与仅具有单个对象属性的 ReportLayout 一起使用,我会得到 - 封闭类型 Framework.Reports.ReportLayout 没有相应的 ReportLayout/LayoutData 可设置属性。我以前遇到过这个错误,我想是时候喝杯咖啡了,忘记通过 WCF 进行延迟加载。
-
嗯...
Report.LayoutData上是否有set? -
@Aron Yes - public virtual ReportLayoutData LayoutData { get;放; }
标签: c# .net wcf entity-framework entity-framework-5