Reputation: 2598
I have 3 classes:
public class Widget
{
public int Id {get; set;}
public string Name {get; set;}
public List<WidgetConfig> Configs {get; set;}
public LabelConfig LabelConfig {get; set;}
}
public class WidgetConfig
{
public int Id {get; set;}
public string Name {get; set;}
public string JsonValue {get; set;}
}
public class LabelConfig
{
public int Type {get; set;}
public string Color {get; set;}
public object Value {get; set;}
}
Entities and Dtos match, so I'll extract one widget so:
var model = await dataContext.Widgets
.Includes(x => x.Configs)
.Select(x => new Dtos.Widget() {
Id = x.Id,
Name = x.Name,
Configs = x.Configs.Select(y => new Dtos.WidgetConfig() {
Id = y.Id,
Name = y.Name,
JsonValue = y.JsonValue
}).ToList(),
LabelConfig = x.Name == "Test"
? JsonConvert.DeserializeObject<LabelConfig>(x.Configs[0].JsonValue)
: null
}).ToListAsync();
Newtonsoft.Json
is used for converting json. I want to calculate directly Widget.LabelConfig
attribute, but this will be null every time.
If I try to convert it after using EF, this will get correct data:
var jsonValue = model.Configs[0].JsonValue;
var convertedObject = JsonConvert.DeserializeObject<LabelConfig>(jsonValue);
model.LabelConfig = convertedObject;
Is it an EF / Linq issue or I do something wrong?
Upvotes: 0
Views: 976
Reputation: 3063
The issue is in the way EF core works and the way you have your query structured. EF core will convert anything before a "hydrating" statement to SQL, but it doesn't know what to do with your LabelConfig statement. However, once you run it through ToListAsync()
, the entities become in-memory objects and LINQ can work as you would expect. So what you need to do is pull the raw data and store it in a string, then convert it after it's been pulled into memory. That can be done by selecting into a new anonymous object that holds your Widget and the string, passing ToList()
once to hydrate, then selecting out of THAT object with the JSON expression to fill it in.
Upvotes: 1