Reputation: 35
I might not fully understand how the backing fields work inside of EF Core, but I'm surprised to see this exception appear when I attempt to save records - and I haven't been able to find any information about it. I am using C# 9 records with change tracking turned off. This is in the context of an ASP.NET Core Web API with Entity Framework Core and a SQLite database. Here are some simplified data models which repro the error:
public record Parent(string Info)
{
//Backing field
private List<Child> children = new();
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; init; } = 0;
public ImmutableList<Child> Children
{
get => children.ToImmutableList();
init => children = value.ToList();
}
}
public record Child(string Info)
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; init; } = 0;
}
The database context:
public class TestContext : DbContext
{
public TestContext(DbContextOptions<TestContext> options) : base(options)
{ }
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Children { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>().HasMany(
parent => parent.Children).WithOne();
}
}
A little controller where I attempt to save a new Parent to the database:
[ApiController]
[Route("[controller]")]
public class ParentController : Controller
{
private readonly TestContext _context;
public ParentController(TestContext context) => _context = context;
[HttpPost]
public ActionResult Create()
{
//Exception thrown:
_context.Parents.Add(new("First")
{
Children = new List<Child>
{
new("First"),
new("Second"),
new("Third")
}.ToImmutableList()
});
_context.SaveChanges();
return Ok();
}
[HttpGet]
public ActionResult<IEnumerable<Parent>> Get()
=> _context.Parents.Include(
parent => parent.Children).ToList();
}
The exception thrown:
System.InvalidOperationException: 'No coercion operator is defined between types 'System.Collections.Generic.List`1[TestAPI.Models.Child]' and 'System.Collections.Immutable.ImmutableList`1[TestAPI.Models.Child]'.'
What's going on behind the scenes here? How do I get around this?
Upvotes: 0
Views: 851
Reputation: 11546
I tried as below
public List<Child> ChildLsit => Children.ToList();
[NotMapped]
public ImmutableList<Child> Children
{
get => children.ToImmutableList();
init => children = value.ToList();
}
this time,it won't get the error you've shown, In my opinion,if you do want to set the property as ImmutableList,you could create a DTO/ViewModel and set the correspond property as ImmutableList then map it to your entity
Upvotes: 0