xcxc0
xcxc0

Reputation: 119

Check a null value in a property attribute field EF Core

How can I check whether an eagerly loaded attribute's filed is null in EF core 6?

Upvotes: 1

Views: 1310

Answers (1)

dani herrera
dani herrera

Reputation: 51715

Quoting MS EF Docs:

Eager loading means that the related data is loaded from the database as part of the initial query.

Then, load it and just check if it is null:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Owner)
        .ToList();

    foreach(var blog in blogs)
    {
        var no_owner = blog.Owner == null; //< -- here
        // ... more code
    }

}

Q (on comments): How can I filter that in Projections? It seems to be not working when using Projections.

Checking null in selection also in projection:

var blogs = 
    db
    .Posts
    .Where(
        p => p.Blog == null // <-- (1)
    )
    .Select( 
        p => new {
            p.Title,
            without_blog = p.Blog == null // <-- (2)
        }
    )
    .ToList();
}

/*
SELECT p.Title, 
       b.BlogId IS NULL AS without_blog // <-- (2)
FROM Posts AS p
LEFT JOIN Blogs AS b ON p.BlogId = b.BlogId
WHERE b.BlogId IS NULL // <-- (1)        
*/

( end of answer )


Just for my future self (or my future me)

I paste here the full text because I know I will need it to help other people. Please, everybody, be free to improve this test, I know it can be better :)

Adding packages:

dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet ef migrations add InitialCreate

Creating dbcontext and models:

using Microsoft.EntityFrameworkCore;
public static class MyDebug
{
    public static string sql {get; set; } = "";
    public static void Capture(string query)
    {
        if (query.Contains("SELECT")) sql = query;
    }
}
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; } = default!;
    public DbSet<Post> Posts { get; set; } = default!;
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseSqlite("Data Source=hello.db")
            .LogTo(MyDebug.Capture);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; } = "";
    public List<Post> Posts { get; set; } = new();
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; } = "";
    public Blog? Blog { get; set; }
}

Testing:

public class ProjectionTest
{
    [Fact]
    public void TestProjection()
    {
        using (var db = new BloggingContext())
        {
            db.Database.Migrate();
            var blogs = 
                db
                .Posts
                .Where(
                    p => p.Blog == null // <-- (1)
                )
                .Select( 
                    p => new {
                        p.Title,
                        without_blog = p.Blog == null // <-- (2)
                    }
                )
                .ToList();
        }
        /*
            SELECT p.Title, 
                   b.BlogId IS NULL AS without_blog // <-- (2)
            FROM Posts AS p
            LEFT JOIN Blogs AS b ON p.BlogId = b.BlogId
            WHERE b.BlogId IS NULL // <-- (1)        
        */
        Assert.Contains("b.BlogId IS NULL AS", MyDebug.sql);
        Assert.Contains("WHERE b.BlogId IS NULL", MyDebug.sql);
    }
}

Upvotes: 3

Related Questions