2011-02-24 82 views
0

我知道“连接”在客户端不支持WCF DS,这就是为什么我决定在服务器端添加一个方法来执行“连接”并返回结果作为自定义类型对象。 服务看起来是这样的:如何在WCF数据服务的服务端执行连接操作

public class CWcfDataService : DataService<CEntities> 
    { 
     // This method is called only once to initialize service-wide policies. 
     public static void InitializeService(DataServiceConfiguration config) 
     { 
      config.UseVerboseErrors = true; 
      config.RegisterKnownType(typeof(CASE_STAGE_HISTORY_EXTENDED)); 
      config.SetEntitySetAccessRule("*", EntitySetRights.All); 
      config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); 
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 
     } 

     [WebGet] 
     public IQueryable<CASE_STAGE_HISTORY_EXTENDED> GetCASE_STAGE_HISTORY_EXTENDEDByDocId(int docId) 
     { 
      CEntities context = new CEntities(); 
      return (from c in context.CASE_STAGE_HISTORY 
        join a in context.USRs on c.CREATOR_ID equals a.USRID 
        select new CASE_STAGE_HISTORY_EXTENDED() 
        { 
         CASE_STAGE_ID = c.CASE_STAGE_HISTORY_ID, 
         CASE_STAGE_NAME = c.CASE_STAGE_NAME, 
         CREATE_DATE = c.CREATE_DATE, 
         CREATOR_ID = c.CREATOR_ID, 
         DOC_ID = c.DOC_ID, 
         LAST_VARIANT_DOCUMENT_ID = c.LAST_VARIANT_DOCUEMENT_ID, 
         CREATOR_FULLNAME = a.FULLNAME 
        }); 
     }  
    } 

和定制类:

[DataServiceKey("CASE_STAGE_ID")] 
    public class CASE_STAGE_HISTORY_EXTENDED 
    { 
     public int CASE_STAGE_ID { get; set; } 
     public int DOC_ID { get; set; } 
     public string CASE_STAGE_NAME { get; set; } 
     public int? LAST_VARIANT_DOCUMENT_ID { get; set; } 
     public DateTime? CREATE_DATE { get; set; } 
     public int? CREATOR_ID { get; set; } 
     public string CREATOR_FULLNAME { get; set; } 
    } 

当我尝试更新Visual Studio的服务参考我不断得到错误:

​​

如果我删除public IQueryable<CASE_STAGE_HISTORY_EXTENDED> GetCASE_STAGE_HISTORY_EXTENDEDByDocId(int docId)部分 - 更新服务参考我得到另一个错误:

The server encountered an error processing the request. The exception message is 'Internal Server Error. The type 'CourtWcf.Code.CASE_STAGE_HISTORY_EXTENDED' is not a complex type or an entity type.'.

环境:Visual Studio 2010中,.NET 4

回答

0

添加了外键并实现了LoadProperty。请参阅我采用此解决方案的文章:http://thedatafarm.com/blog/data-access/the-cost-of-eager-loading-in-entity-framework/ 仍然如果我在数据库中没有关系(例如,我没有外键) - 我有另一种解决方案:创建存储过程并将其与数据库模型中的导入进行映射。之后,创建复杂类型,也可以在客户端工作(你必须通过URI访问它,而不是使用lambda扩展)。见示例here
非常感谢在这个主题中的其他回答者,您让我更深入了解这个主题。

-2

对于初学者来说,WCF不支持IQueryable的。那就是你的问题。

在你的情况IEnumerable应该工作。

你应该将服务看作是具有方法并返回“数据”的东西。这些数据可以是单个值,对象实例或对象集合。客户不应该考虑调用服务来进行连接,而应该“给我这些和那些数据 - 给定这些参数”。

您的方法名赋予正确的“intent”GetCaseStageHistoryExtendedByDocId(int docId),并且您返回的是CASE_STAGE_HISTORY_EXTENDED对象的集合。而已。

IQueryable意味着完全不同的东西,这个概念不属于服务本身。

编辑

尝试通过调用就可以了ToList()方法,将您的可查询到列表中。

返回(从C中context.CASE_STAGE_HISTORY 加入在上c.CREATOR_ID context.USRs等于a.USRID 选择新CASE_STAGE_HISTORY_EXTENDED() { CASE_STAGE_ID = c.CASE_STAGE_HISTORY_ID, CASE_STAGE_NAME = c.CASE_STAGE_NAME, 。CREATE_DATE = c.CREATE_DATE, CREATOR_ID = c.CREATOR_ID, DOC_ID = c.DOC_ID, LAST_VARIANT_DOCUMENT_ID = c.LAST_VARIANT_DOCUEMENT_ID, CREATOR_FULLNAME = a.FULLNAME })ToList();

请注意,您只能将可序列化对象发送到客户端。所以首先确保你的对象是可序列化的。

+0

异常消息是'无法加载方法'System.Collections.Generic.IEnumerable'1 [CWcf.Code。')的'返回类型的元数据'System.Collections.Generic.IEnumerable'1 [CWcf.Code.CASE_STAGE_HISTORY_EXTENDED]'。 CASE_STAGE_HISTORY_EXTENDED] GetCASE_STAGE_HISTORY_EXTENDEDByDocId(Int32)'。'。 – 0x49D1 2011-02-24 10:06:43

+0

你的类型是可串行化的吗?你测试过它是可序列化的吗? – 2011-02-24 10:16:53

+0

@nihi_l_ist,尝试在返回之前通过调用ToList()方法将查询转换为“List”。 – 2011-02-24 10:22:55

0

我假设数据服务基于实体框架模型(CEntities类是一个ObjectContext)。 如果是这种情况,则类型完全从EF模型(CSDL)中读取,而类定义或多或少被忽略。所以你需要在EF模型中定义服务操作返回的类型。还要注意,为了让IQueryable工作,该类型必须被EF识别为实体类型(这可能需要映射到数据库,或者EF专家会知道更多)。