我有两个相互引用的物体。
[JsonObject(IsReference = true)]
[DataContract(IsReference = true, Namespace = "http://schemas.datacontract.org/2004/07/TrackableEntities.Models")]
[ProtoContract]
public class ProtoBufObject : ITrackable
{
[DataMember(Order = 3)]
public Guid Oid { get; set; }
[DataMember(Order = 4)]
[ProtoMember(4, AsReference = true)]
public ChildProtoBufObject child { get; set; }
[DataMember(Order = 1)]
public TrackingState TrackingState { get; set; }
[DataMember(Order = 2)]
public ICollection<string> ModifiedProperties { get; set; }
}
[JsonObject(IsReference = true)]
[DataContract(IsReference = true, Namespace = "http://schemas.datacontract.org/2004/07/TrackableEntities.Models")]
[ProtoContract]
public class ChildProtoBufObject : ITrackable
{
[DataMember(Order = 3)]
public Guid Oid { get; set; }
[DataMember(Order = 4)]
[ProtoMember(4, AsReference = true)]
public ProtoBufObject parent { get; set; }
[DataMember(Order = 1)]
public TrackingState TrackingState { get; set; }
[DataMember(Order = 2)]
public ICollection<string> ModifiedProperties { get; set; }
}
在客户端上,我实例化这些对象并制作&#34; association&#34;。
ProtoBufObject parent = new ProtoBufObject()
{
Oid = Guid.NewGuid()
};
ChildProtoBufObject child = new ChildProtoBufObject()
{
Oid = Guid.NewGuid()
};
parent.child = child;
child.parent = parent;
对象将按如下方式序列化:
ProtoBufFormatter formatter = new ProtoBufFormatter();
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, requestUri);
requestMessage.Content = new ObjectContent<SearchParameters>(searchParameters, formatter);
而且它们将通过http发送到Webapi,在那里它将被反序列化 在WebApiContrib.Formatting.ProtoBuf。
的帮助下在Webapi控制器中,我接收到具有正确关系的对象,但关系的完整性出错了。我用Json将对象转储到一个文件中:
string json = JsonConvert.SerializeObject(samples);
//write string to file
string oid = samples.First().Oid.ToString();
System.IO.File.WriteAllText(@"D:\JsonTest\dummypath" + oid + ".txt", json);
以下是此文本文件的内容
[{
"$id": "1",
"TrackingState": 0,
"ModifiedProperties": null,
"Oid": "8c00ea73-ac84-4130-b1a8-61e1df89f9bf",
"child": {
"$id": "2",
"TrackingState": 0,
"ModifiedProperties": null,
"Oid": "81026a01-7de2-4045-ac0a-314b3fd7360c",
"parent": {
"$id": "3",
"TrackingState": 0,
"ModifiedProperties": null,
"Oid": "8c00ea73-ac84-4130-b1a8-61e1df89f9bf",
"child": {
"$ref": "2"
}
}
}
}]
孩子有一个新的&#34; id = 3而不是ref = 1的父级。
id = 3父级具有对孩子的正确引用。
所以它接缝顶级对象将无法正确设置。这是实体框架的一个大问题(这就是我提出这个问题的原因)因为它使用了类型的引用,而不仅仅是属性(这是正确的)。
我也尝试使用ProtoContract(DefaultRefencetype = true),但这使它更加糟糕。然后我收到id = 3的父母,一个id = 4的新孩子。
我的问题是:如何使对象的完整性发挥作用?
我想要的是:
[{
"$id": "1",
"TrackingState": 0,
"ModifiedProperties": null,
"Oid": "8c00ea73-ac84-4130-b1a8-61e1df89f9bf",
"child": {
"$id": "2",
"TrackingState": 0,
"ModifiedProperties": null,
"Oid": "81026a01-7de2-4045-ac0a-314b3fd7360c",
"parent": {
"$ref": "1"
}
}
}
}]
编辑: 实体框架行
dbContext.Set<ProtoBufObject>.AddRange(myObjects);
抛出InvalidOperationException,因为模型(parent,child.parent)的完整性不同。
Additional information: Conflicting changes to the role 'foo_bar_Target' of the relationship 'Entities.Context.foo_bar' have been detected.
如果我在客户端使用Newtonsoft.Json序列化程序并通过WebApi发送它(我使用与我的Protobuf测试具有相同关系的相同对象),Entity Framework可以处理这些对象。因此,Json和Protobuf的反序列化对象之间必定存在一些差异。这就是为什么我再次序列化对象以查看差异的原因。
我还在Put方法中添加了参考检查:
if (protoBufObject != protoBufObject.child.parent)
{
throw new Exception("Instance integrity differs!");
}
从json文件中预期会抛出此异常,因此引用确实已损坏。
在WebApi的启动中,我使用以下代码:
config.Formatters.Add(new ProtoBufFormatter());
有问题吗?我是否需要向格式化程序添加更多信息?