Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InMemory implicitly deletes entity when changed to an invalid state #13320

Closed
gojanpaolo opened this issue Sep 13, 2018 · 2 comments
Closed

InMemory implicitly deletes entity when changed to an invalid state #13320

gojanpaolo opened this issue Sep 13, 2018 · 2 comments

Comments

@gojanpaolo
Copy link

A Post with null Blog can be saved using the in-memory provider even if the Post.BlogId is non-nullable. But when a Post is saved with a Blog instance and then later changed to null, the said Post entity will be implicitly deleted.

Steps to reproduce

using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using Xunit;

public class Tests
{
    private readonly DbContextOptions<Context> _options;

    public Tests()
    {
        _options = new DbContextOptionsBuilder<Context>()
            .UseInMemoryDatabase(Guid.NewGuid().ToString())
            .Options;
    }

    [Fact]
    public void Can_save_Post_with_null_Blog()
    {
        using (var ctx = new Context(_options))
        {
            ctx.Add(new Post { Blog = null });
            ctx.SaveChanges();
        }

        using (var ctx = new Context(_options))
        {
            Assert.NotEmpty(ctx.Post);
        }
    }

    [Fact]
    public void In_memory_implicitly_deletes_Post_when_Blog_is_set_to_null()
    {
        using (var ctx = new Context(_options))
        {
            ctx.Add(new Post { Blog = new Blog() });
            ctx.SaveChanges();
        }

        using (var ctx = new Context(_options))
        {
            ctx.Post.Include(p => p.Blog).First().Blog = null;
            ctx.SaveChanges();
        }

        using (var ctx = new Context(_options))
        {
            Assert.NotEmpty(ctx.Post);
        }
    }
}

public class Context : DbContext
{
    public Context(DbContextOptions<Context> options) : base(options) { }
    public DbSet<Post> Post { get; set; }
    public DbSet<Blog> Blog { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

public class Blog
{
    public int BlogId { get; set; }
}

Further technical details

EF Core version: 2.1.3
Database Provider: Microsoft.EntityFrameworkCore.InMemory
Operating system: Win7
IDE: Visual Studio 2017 15.4

@ajcvickers
Copy link
Member

@gojanpaolo For the first case, the save is not throwing because the in-memory provider currently doesn't enforce relational constraints--see #2166.

For the second case, Post.BlogId is not nullable, which implies a required relationship between Blog and Post. This means that when the relationship is severed the default behavior is to delete the dependent (Post) since it can't exist without it's parent. See https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete

@gojanpaolo
Copy link
Author

I see now. Thank you @ajcvickers.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants