C# WCF数据服务中如何在服务端进行连接操作
我知道WCF DS在客户端不支持“join”,这就是为什么我决定在服务器端添加一个方法来执行“join”,并将结果作为自定义类型对象返回。 服务如下所示: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
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.IQueryable1[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.List1[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; }
}