Я хочу сохранить снимок вложенной модели в моей базе данных как историю изменений. Поэтому я сделал модель, которая сериализует весь объект в строку JSON для упрощения хранения.
Упрощенный Data
класс, который я хочу сохранить:
public class Data
{
public int Id { get; set; }
public string SomeInfo { get; set; }
public virtual ICollection<DataObject> DataObject { get; set; }
}
DataObject
для коллекциивнутри Data
:
public class DataObject
{
public int Id { get; set; }
public string SomeMoreInfo { get; set; }
public int DataId { get; set; }
public virtual Data Data { get; set; }
}
Мой класс снимков выглядит примерно так:
public class DataHistory
{
public int Id { get; set; }
private string _Data;
[NotMapped]
public Data Data
{
get { return _Data == null ? null : JsonConvert.DeserializeObject<Data>(_Data); }
set { _Data = JsonConvert.SerializeObject(value , Formatting.Indented,
new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
PreserveReferencesHandling = PreserveReferencesHandling.None
});
}
}
}
Внутри моего контроллера я делаю:
var data = await _repo.GetData(id);
var historyEntry = new DataHistory();
historyEntry.Data= data;
_repo.Add(historyEntry);
GetData()
методвнутри репозитория:
public async Task<Data> GetData(int id)
{
return await _context.Data
.Include(d => d.DataObject)
.FirstOrDefaultAsync(d => d.Id == id);
}
Проблема в том, что когда я пытаюсь сериализовать одну запись Data
, я получаю собственную ссылку внутри DataObject
, поэтому она снова включает в себя объект Data
, а также DataObjects
. Даже с ReferenceLoopHandling.Ignore
полученный JSON выглядит примерно так:
{
"Id": 1051,
"SomeInfo": "asdasd",
"DataObject": [
{
"Id": 121,
"SomeMoreInfo": "asdasd",
"Data": {
"Id": 1051,
"SomeInfo": "asdasd",
"DataObject": [
{
"Id": 122,
"SomeMoreInfo": "asdasd",
"DataId": 1051
}
]
}
},
{
"Id": 122,
"SomeMoreInfo": "asdasd",
"Data": {
"Id": 1051,
"SomeInfo": "asdasd",
"DataObject": [
{
"Id": 121,
"SomeMoreInfo": "asdasd",
"DataId": 1051
}
]
}
}
]
}
РЕДАКТИРОВАТЬ: Ожидаемый результат будет примерно таким:
{
"Id": 1051,
"SomeInfo": "Data",
"DataObject": [
{
"Id": 121,
"SomeMoreInfo": "DataObject1"
"DataId": 1051
},
{
"Id": 122,
"SomeMoreInfo": "DataObject2"
"DataId": 1051
}
]
}
Как я могуостановить его от включения Data
во второй раз без использования DTO?
РЕДАКТИРОВАТЬ:
Если я попробую это без Entity Framework, ReferenceLoopHandling.None
будет работать как положено. См. Dotnet Fiddle https://dotnetfiddle.net/bmAoAW. Так что, похоже, проблема с моей конфигурацией EF Core или чем-то подобным.