How to store JSON in an entity field with EF Core?
@Michael's answer got me on track but I implemented it a little differently. I ended up storing the value as a string in a private property and using it as a "Backing Field". The ExtendedData property then converted JObject to a string on set and vice versa on get:
public class Campaign
{
// https://learn.microsoft.com/en-us/ef/core/modeling/backing-field
private string _extendedData;
[Key]
public Guid Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
[NotMapped]
public JObject ExtendedData
{
get
{
return JsonConvert.DeserializeObject<JObject>(string.IsNullOrEmpty(_extendedData) ? "{}" : _extendedData);
}
set
{
_extendedData = value.ToString();
}
}
}
To set _extendedData
as a backing field, I added this to my context:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Campaign>()
.Property<string>("ExtendedDataStr")
.HasField("_extendedData");
}
Update: Darren's answer to use EF Core Value Conversions (new to EF Core 2.1 - which didn't exist at the time of this answer) seems to be the best way to go at this point.
Best way to update JSON property with EF core
Its not possible as of EF Core 2.2. There is a proposal for such a feature, but I would not hold my breath.
If the JSON you are storing is small and/or the updates are rare I would go with the first approach as the changes are stored in the context and you don't need a transaction and aligns better with the overall design of EF. Plus it gives you compile time safety and is easier to refactor/change. Check this thread out - How to store JSON in an entity field with EF Core?
If you need performance than definitely the JSON_MODIFY sql command.
Searching in sql server json column and consume it using entity framework core
Well - you could use Value conversion:
https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations#composite-value-objects
Another option would be to create a keyless entity for that specific query:
https://learn.microsoft.com/en-us/ef/core/modeling/keyless-entity-types?tabs=data-annotations
Edit: here's a bit on how to setup a keyless entity.
https://stackoverflow.com/a/69924584/4122889
Mapping json in EF Core 3
Since you're saving the City.Stores
collection as a JSON serialized string, you cannot use it as a navigation collection to child objects. You need to get rid of the .Include(x => x.Stores)
in the query statement:
var res = _db.Cities.Where(x => x.Id == id)
.Include(x => x.Parks) // this works fine
.FirstOrDefault();
Save Collection As JSON with Entity Framework
The problem with the accepted answer is that any changes to the contents of the list (adding, modifying or deleting entries) won't be tracked by EF.
Here is my solution, inspired by this excellent blog post.
This class takes care of serializing and deserializing so that the collection can be stored in a single column on the parent model:
[ComplexType]
public class DateTimeCollection : Collection<DateTime>
{
public void AddRange(IEnumerable<DateTime> collection)
{
foreach (var item in collection)
{
Add(item);
}
}
[Column("Times")]
public string Serialized
{
get { return JsonConvert.SerializeObject(this); }
private set
{
if (string.IsNullOrEmpty(value))
{
Clear();
return;
}
var items = JsonConvert.DeserializeObject<DateTime[]>(value);
Clear();
AddRange(items);
}
}
}
That's it! You can now use this new collection on your parent class exactly as you'd expect. Changes to the contents of the collection will be tracked.
public class Company{
// ...
public DateTimeCollection Times { get; set; }
}
Entity Framework Core jsonb column type
Based on H. Herzl comment:
My final solution was something like this:
public class MyTableClass
{
public int Id { get; set; }
[Column(TypeName = "jsonb")]
public string Data { get; set; }
}
Migrations generated this:
Data = table.Column<string>(type: "jsonb", nullable: true),
When updated the database with migrations, the Data column was created correctly with jsonb type.
Thank you H. Herzl!
Related Topics
Send JSON via Post in C# and Receive the JSON Returned
Complex Models and Partial Views - Model Binding Issue in ASP.NET MVC 3
How to Show a Image in Database in the Image Control of ASP.NET
Rounding Up to 2 Decimal Places in C#
Is It There Any Lru Implementation of Idictionary
How to Translate Cultureinfo Language Names
How to Convert a Character in to Equivalent System.Windows.Input.Key Enum Value
Creating a SQL Server Table from a C# Datatable
How to Perform an Insert and Return Inserted Identity with Dapper
Why Folderbrowserdialog Dialog Does Not Scroll to Selected Folder
What's Wrong with These Parameters
How to Clear Event Subscriptions in C#
What's the Difference Between Using the Serializable Attribute & Implementing Iserializable
Accelerating Bitmap Grayscale Conversion, Is Openmp an Option in C#