C# WCF数据服务中如何在服务端进行连接操作

C# WCF数据服务中如何在服务端进行连接操作,c#,entity-framework,exception,join,wcf-data-services,C#,Entity Framework,Exception,Join,Wcf Data Services,我知道WCF DS在客户端不支持“join”,这就是为什么我决定在服务器端添加一个方法来执行“join”,并将结果作为自定义类型对象返回。 服务如下所示: public class CWcfDataService : DataService<CEntities> { // This method is called only once to initialize service-wide policies. public static voi

我知道WCF DS在客户端不支持“join”,这就是为什么我决定在服务器端添加一个方法来执行“join”,并将结果作为自定义类型对象返回。 服务如下所示:

 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
                    });
        }    
    }
当我尝试在Visual Studio中更新服务引用时,经常会出现以下错误:

服务器遇到错误 处理请求。例外 消息“无法加载元数据” 对于返回类型 “System.Linq.IQueryable
1[CWcf.code.CASE\u STAGE\u HISTORY\u EXTENDED]”
方法论
'System.Linq.IQueryable
1[CWcf.code.CASE\u STAGE\u HISTORY\u EXTENDED] GetCASE_STAGE_HISTORY_EXTENDEDByDocId(Int32)'”。 有关详细信息,请参阅服务器日志

如果我删除了
public IQueryable GetCASE\u STAGE\u HISTORY\u EXTENDEDByDocId(int docId)
部分-在更新服务引用时,我会遇到另一个错误:

服务器遇到错误 处理请求。例外 消息是“内部服务器错误”。这个 类型 'CourtWcf.Code.CASE\u STAGE\u HISTORY\u EXTENDED' 不是复杂类型或实体 类型


环境:Visual Studio 2010,.NET 4

首先,WCF不支持IQueryable。这就是你的问题所在

在您的情况下,IEnumerable应该起作用

您应该将服务视为具有方法并返回“数据”的东西。这些数据可以是单个值、对象实例或对象集合。客户机不必考虑调用服务来进行连接,而是“给我一些这样或那样的数据——给定这些参数”

方法名传递了正确的“intent”GetCaseStageHistoryExtendedByDocId(int-docId),返回的是CASE\u-STAGE\u-HISTORY\u扩展对象的集合。就这样

IQueryable意味着完全不同的东西,并且该概念不适用于服务本身

编辑

尝试通过调用ToList()方法将查询表转换为列表

返回(在context.CASE\u STAGE\u历史中从c返回) 在c.CREATOR_ID等于a.USRID上的context.USRs中加入a 选择新案例\阶段\历史\扩展() { CASE\u STAGE\u ID=c.CASE\u STAGE\u HISTORY\u ID, CASE_STAGE_NAME=c.CASE_STAGE_NAME, 创建日期=c.创建日期, 创建者ID=c.CREATOR\u ID, DOC\u ID=c.DOC\u ID, 最后一个变量文档ID=c。最后一个变量文档ID, CREATOR\u FULLNAME=a.FULLNAME }).ToList()


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

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

添加了外键并实现了LoadProperty。请参阅我采用此解决方案的文章:
但若我在数据库中并没有关系(例如,我并没有外键),那个么我还有另一个解决方案:创建存储过程,并在数据库模型中将其映射为import。之后,创建复杂类型,该类型也将在客户机中工作(但您必须通过URI访问它,而不是使用lambda扩展)。参见示例。
非常感谢此线程中的其他回答者,您让我深入了解了主题。

异常消息是“无法加载返回类型的元数据”System.Collections.Generic.IEnumerable
1[CWcf.code.CASE\u STAGE\u HISTORY\u EXTENDED]“of method”System.Collections.Generic.IEnumerable
1[CWcf.Code.CASE_STAGE_HISTORY_EXTENDED]GetCASE_STAGE_HISTORY_EXTENDED bydocid(Int32)”。您的类型可序列化吗?您是否测试过它可序列化?@nihi_l_ist,在返回之前通过调用ToList()方法尝试将查询转换为“列表”。@Shiv Kumar,我添加了[serializable]属性并更改了要列出的方法的返回类型…仍然:异常消息为“无法加载返回类型的元数据”System.Collections.Generic.List
1[CWcf.code.CASE\u STAGE\u HISTORY\u EXTENDED]“of method”System.Collections.Generic.List
1[CWcf.code.CASE\u STAGE\u HISTORY\u EXTENDED]GetCASE_STAGE_HISTORY_EXTENDEDByDocId(Int32)“.”。我想这个问题与dataContext有关?我不是一个真正与WCF相关的问题,而是与您正在使用的对象有关。也许这个链接上的文章会有所帮助。
   [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; }
    }