EF Core LINQ Query Fails to Set Property Values in Projection

.NET projects using Entity Framework Core sometimes encounter a peculiar issue when projecting query results into view models. Consider the following entities:

public class Cat
{
    public string? Name { get; set; }
    public string? MasterId { get; set; }
}

public class User
{
    public string? Id { get; set; }
    public string? Name { get; set; }
}

And a view object:

public class CatVo
{
    public string? Name { get; set; }
    public string? MasterName { get; set; }
}

When attempting to populate a list of CatVo with the master's name via a LINQ query inside a service:

public class Service
{
    private readonly DbSet<Cat> _cats;
    private readonly DbSet<User> _users;

    public Service(DbSet<Cat> cats, DbSet<User> users)
    {
        _cats = cats;
        _users = users;
    }

    public List<CatVo> Serve()
    {
        List<CatVo> result = _cats.Select(cat => new CatVo
        {
            Name = cat.Name,
            MasterName = _users.Single(user => user.Id == cat.MasterId).Name
        }).ToList();

        return result;
    }
}

The resulting list contains only Name values; MasterName remains null.

This behavior stems from how EF Core processes LINQ expressions. When the query is translated to SQL, the property setter in side the projection (MasterName = _users.Single(...).Name) is not executed as C# code. Instead, the epxression is converted to a database command. Since setting a property on a transient object does not correspond to any database change, EF Core’s query pipeline may skip the assignment entirely. The setter is only invoked when the context tracks changes, such as during SaveChanges. For read-only projections, the assignment is lost.

To work around this, materialize the query first, then populate the additional property in a separate step:

public List<CatVo> Serve()
{
    List<CatVo> result = _cats.Select(cat => new CatVo
    {
        Name = cat.Name
    }).ToList();

    foreach (var vo in result)
    {
        var catEntity = _cats.Single(c => c.Name == vo.Name);
        var user = _users.Single(u => u.Id == catEntity.MasterId);
        vo.MasterName = user.Name;
    }

    return result;
}

By converting to a list first, the property assignmants happen in-memory and work as expected.

Tags: Entity Framework Core LINQ .NET

Posted on Wed, 17 Jun 2026 17:56:58 +0000 by slick101