【发布时间】:2021-08-19 14:11:50
【问题描述】:
也许有点奇怪的用例,但我需要将大量 json 放入数据库,但问题是我需要的 json 对象中多次出现 author 对象引用同一个作者对象。
例如:
public class Book
{
public string Title { get; set; }
public string Genre { get; set; }
public Author Author { get; set; }
public List<Author> Reviewers { get; set; }
}
public class Author
{
public string Id { get; set; }
public string Name{ get; set; }
}
// data.json
{
"title": "...",
"genre": "...",
"author": { // Deserializes into Author class
"id": "1"
"name": "..."
},
"reviewers": [ // Deserializes into List<Author>
{
"id": "1", // Needs to point to same object as "author"
"name": "..."
},
{
"id": "2",
"name": "..."
}
]
}
在此示例中,由于 Entity Framework Core 要求不能跟踪具有相同 Id 的两个对象,因此当我需要它们引用同一个对象时,具有相同 Id 的作者被反序列化为两个不同的对象。
System.InvalidOperationException:
'The instance of entity type 'Author' cannot be tracked because another instance with the key
value '{Id: 1}' is already being tracked. When attaching existing entities, ensure that only
one entity instance with a given key value is attached.'
【问题讨论】:
-
json 只是一个例子,不是实际数据。不需要
Reviewer类,因为它与Author格式相同,它们是相同的。我希望它们指向数据库中的同一个表。 -
System.Text.Json 确实支持引用跟踪,请参阅How to preserve references and handle or ignore circular references in System.Text.Json 了解如何做到这一点。但请注意,格式不同,它使用
"$id"和"$ref"属性。你能改变你的JSON格式吗?该功能是否满足您的需求? -
@dbc 我看了看并尝试创建一个处理程序,但我不控制 json 格式。有没有办法将引用解析器设置为使用
id? -
我不相信 System.Text.Json (或 Newtonsoft 就此而言)是可能的。请参阅the docs for
ReferenceHandler.Preserve,其中没有提到重命名属性的能力。您可能需要一个自定义转换器,在反序列化时您是否可以控制您的JsonSerializerOptions? -
是的。我一直在努力设置一个自定义解析器,但是有很多对象被反序列化,我只关心
Author引用
标签: c# json .net entity-framework-core system.text.json