关注Error with explicit conversion when using CollectAs<>
中的问题来自WebMethod的代码
return client.Cypher
.Match("(person:Person)")
.Where((Person person) => person.Email == username)
.OptionalMatch("(person)-[:SPEAKS]-(language:Language)")
.OptionalMatch("(person)-[:CURRENT_LOCATION]-(country:Country)"
.Return((person, language, country) => new ProfileObject
{
Person = person.As<Person>(),
Language = language.CollectAs<Language>(),
Country = country.CollectAs<Country>()
}).Results.ToList();
国家/地区类代码:
public class Language
{
public string Name { get; set; }
}
ProfileObject类的新代码:
public class ProfileObject
{
public Person Person { get; set; }
public IEnumerable<Node<Language>> Language { get; set; }
public IEnumerable<Node<Country>> Country { get; set; }
}
只有当我将ProfileObject设置为返回IEnumerable&gt;时才会出现此错误,如果我将其返回到
public Country Country {get; set;}
然后它可以工作(但我显然会为每个返回的Country对象获得重复的Person条目。
任何人都能告诉我这个问题的解决方案并不会让我把所有代码都删掉并重新开始吗?
更新
[InvalidOperationException:Neo4jClient.Node`1 [Graph.Language]无法序列化,因为它没有无参数构造函数。]
[InvalidOperationException:无法序列化成员&#39; Graph.ProfileObject.Language&#39;类型&#39; System.Collections.Generic.List
1[[Neo4jClient.Node
1 [[Graph.Language,Graph,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]],Neo4jClient,Version = 0.0.0.0 ,Culture = neutral,PublicKeyToken = null]]&#39;,请参阅内部异常以获取更多详细信息。 System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc,MemberInfo成员,类型类型)+5451673 System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc,MemberInfo成员,类型类型)+69 System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo)+125 System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo)+89 System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping,StructModel model,Boolean openModel,String typeName,RecursionLimiter limiter)+618 System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model,String ns,Boolean openModel,XmlAttributes a,RecursionLimiter limiter)+378 System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model,String ns,ImportContext context,String dataType,XmlAttributes a,Boolean repeats,Boolean openModel,RecursionLimiter limiter)+1799[InvalidOperationException:反映类型错误&#39; Graph.ProfileObject&#39;。] System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model,String ns,ImportContext context,String dataType,XmlAttributes a,Boolean repeats,Boolean openModel,RecursionLimiter limiter)+1917 System.Xml.Serialization.XmlReflectionImporter.CreateArrayElementsFromAttributes(ArrayMapping arrayMapping,XmlArrayItemAttributes attributes,Type arrayElementType,String arrayElementNs,RecursionLimiter limiter)+263 System.Xml.Serialization.XmlReflectionImporter.ImportArrayLikeMapping(ArrayModel model,String ns,RecursionLimiter limiter)+264 System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor,FieldModel model,XmlAttributes a,String ns,Type choiceIdentifierType,Boolean rpc,Boolean openModel,RecursionLimiter limiter)+5456308 System.Xml.Serialization.XmlReflectionImporter.ImportMemberMapping(XmlReflectionMember xmlReflectionMember,String ns,XmlReflectionMember [] xmlReflectionMembers,Boolean rpc,Boolean openModel,RecursionLimiter limiter)+852 System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember [] xmlReflectionMembers,String ns,Boolean hasWrapperElement,Boolean rpc,Boolean openModel,RecursionLimiter limiter)+286
[InvalidOperationException:有一个错误反映了&#39; MyResult&#39;。] System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember [] xmlReflectionMembers,String ns,Boolean hasWrapperElement,Boolean rpc,Boolean openModel,RecursionLimiter limiter)+979 System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(String elementName,String ns,XmlReflectionMember [] members,Boolean hasWrapperElement,Boolean rpc,Boolean openModel,XmlMappingAccess access)+133 System.Web.Services.Protocols.SoapReflector.ImportMembersMapping(XmlReflectionImporter xmlImporter,SoapReflectionImporter soapImporter,Boolean serviceDefaultIsEncoded,Boolean rpc,SoapBindingUse use,SoapParameterStyle paramStyle,String elementName,String elementNamespace,Boolean nsIsDefault,XmlReflectionMember [] members,Boolean validate,Boolean openModel, String key,Boolean writeAccess)+240 System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo,Boolean client,XmlReflectionImporter xmlImporter,SoapReflectionImporter soapImporter,String defaultNs)+2893
[InvalidOperationException:Method ProfileServices.My无法反映。] System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo,Boolean client,XmlReflectionImporter xmlImporter,SoapReflectionImporter soapImporter,String defaultNs)+6173 System.Web.Services.Description.SoapProtocolReflector.ReflectMethod()+137 System.Web.Services.Description.ProtocolReflector.ReflectBinding(ReflectedBinding reflectBinding)+1776 System.Web.Services.Description.ProtocolReflector.Reflect()+641 System.Web.Services.Description.ServiceDescriptionReflector.ReflectInternal(ProtocolReflector [] reflectors)+685 System.Web.Services.Description.ServiceDescriptionReflector.Reflect(Type type,String url)+118 System.Web.Services.Protocols.DocumentationServerType..ctor(Type type,String uri,Boolean excludeSchemeHostPortFromCachingKey)+230 System.Web.Services.Protocols.DocumentationServerProtocol.Initialize()+ 434 System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type,HttpContext context,HttpRequest request,HttpResponse response,Boolean&amp; abortProcessing)+122
[InvalidOperationException:无法处理请求。] System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type,HttpContext context,HttpRequest request,HttpResponse response,Boolean&amp; abortProcessing)+320 System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type,HttpContext context,HttpRequest request,HttpResponse response)+171
[InvalidOperationException:无法处理请求。] System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type,HttpContext context,HttpRequest request,HttpResponse response)+374 System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context,String verb,String url,String filePath)+209 System.Web.Script.Services.ScriptHandlerFactory.GetHandler(HttpContext context,String requestType,String url,String pathTranslated)+48 System.Web.HttpApplication.MapHttpHandler(HttpContext context,String requestType,VirtualPath path,String pathTranslated,Boolean useAppConfig)+226 System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+ 145 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+155
答案 0 :(得分:3)
默认情况下,asp.net使用DataContractSerializer
序列化为XML,但错误消息"Cannot serialize member <x> because it is an interface"
为generated by XmlSerializer
,因此显然您已切换到该值。
您可以考虑切换回指定here的DataContractSerializer
,只要基础类型IEnumerable<T>
可以序列化,就可以序列化T
类型的属性。
或者,如果您不想这样做,您可以修改ProfileObject
类以返回代理数组以进行序列化,而无需更改基础设计:
public class ProfileObject
{
public Person Person { get; set; }
[XmlIgnore]
public IEnumerable<Node<Language>> Language { get; set; }
[XmlIgnore]
public IEnumerable<Node<Country>> Country { get; set; }
[XmlArray("Languages")]
[XmlArrayItem("Language")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public Node<Language>[] LanguageArray
{
get
{
if (Language == null)
return null;
return Language.ToArray();
}
set
{
Language = value;
}
}
[XmlArray("Countries")]
[XmlArrayItem("Country")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public Node<Country>[] CountryArray
{
get
{
if (Country == null)
return null;
return Country.ToArray();
}
set
{
Country = value;
}
}
}
<强>更新强>
XmlSerializer
只会使用公开get
和set
方法序列化属性。由于Node.Data
仅限get,因此无法按XmlSerializer
序列化。
由于您只需序列化数据而不需要Node<TData>
,并且永远不需要反序列化,您可以使用linq将您的可枚举节点转换为用于序列化的数据数组,如下所示:
public static class NodeExtensions
{
public static TData [] ToDataArray<TData>(this IEnumerable<Node<TData>> nodes)
{
if (nodes == null)
return null;
return nodes.Select(n => n.Data).ToArray();
}
}
public class ProfileObject
{
public Person Person { get; set; }
[XmlIgnore]
public IEnumerable<Node<Language>> Language { get; set; }
[XmlIgnore]
public IEnumerable<Node<Country>> Country { get; set; }
[XmlArray("ArrayOfLanguage")]
[XmlArrayItem("Language")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public Language [] LanguageArray
{
get
{
return Language.ToDataArray();
}
set
{
throw new NotImplementedException();
}
}
[XmlArray("ArrayOfCountry")]
[XmlArrayItem("Country")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public Country [] CountryArray
{
get
{
return Country.ToDataArray();
}
set
{
throw new NotImplementedException();
}
}
}
答案 1 :(得分:1)
因此,您不需要向Node<T>
类添加任何更改,它应该将所有内容反序列化。
所以,这是我目前的设置:
public class Country
{
public string Name { get; set; }
}
public class Language
{
public string Name { get; set; }
}
public class ProfileObject
{
public Person Person { get; set; }
public IEnumerable<Node<Language>> Language { get; set; }
public IEnumerable<Node<Country>> Country { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Email { get; set; }
}
你没有定义Country
或Person
所以我已经制定了它们,但实质上我觉得它非常接近。现在我将我的数据库初始化为:
(PERSON)-[:SPEAKS]->(ENGLISH)
(PERSON)-[:SPEAKS]->(GERMAN)
(PERSON)-[:CURRENT_LOCATION]->(GERMANY)
首先,按原样运行查询&#39; (即直接从此页面复制)在序列化方面对我来说很好用 - 您能否确认您的Language
,Person
,Country
和ProfileObject
和您一样# 39; ve定义了默认构造函数还是显式无参数构造函数?
关于你期待什么 - 我想你是在ProfileObject
之后拥有2个Language
个对象,而且只有1 Country
。现在,您编写的查询将转换为Cypher,如下所示:
MATCH (person:Person)
WHERE (person.Email = "THE EMAIL ADDRESS HERE")
OPTIONAL MATCH (person)-[:SPEAKS]-(language:Language)
OPTIONAL MATCH (person)-[:CURRENT_LOCATION]-(country:Country)
RETURN person AS Person, collect(language) AS Language, collect(country) AS Country
如果你在Neo4j管理器(localhost:7474)中运行它并切换到&#39;行&#39;查看(从图表中)您将看到您实际上以您在客户端中获得的形式返回数据。
我会在neo4j管理视图中调整查询,直到得到你想要的结果。之后可能不值得返回CollectAs
并执行LINQ .Group
。