This code works as expected: the ExhibitionName
property brings the concatenation of the fields according to their values.
public partial class Client
{
public int Id { get; set; }
public int Reference { get; set; }
[StringLength(100)]
public string Name{ get; set; } = null!;
[StringLength(50)]
public string? Nickname{ get; set; }
public string ExhibitionName => (!String.IsNullOrWhiteSpace(Nickname) ? Nickname: Name) + " (" + Reference+ ")";
public DateOnly Added { get; set; }
// other properties
}
// db is the DbContext instance for Client.
db.Clients.Select(c => new { c.Id, c.ExhibitionName }).ToList();
However, the SQL statement generated by Entity Framework returns all the columns from the table, even the ones not related, which is not desirable.
The second option would be to use HasComputedColumnSql
in the model mapping and achieve the same result via the database.
Is there a third option?
That is, because with your current implementation, the ExhibitionName
is not mapped into column in your database. The output looks like:
SOLUTION
One of the solutions as you mentioned is to use HasComputedColumnSql
or HasValueGenerator
To apply that, simply change your property into:
[JsonIgnore]
public string ExhibitionName { get; set; }
Then inside the OnModelCreating
method add:
modelBuilder.Entity<Client>().Property(x => x.ExhibitionName)
.HasValueGenerator<ExhibitionNameGenerator>();
The last step is to create a generator, the sample implementation can looks like this:
public class ExhibitionNameGenerator : ValueGenerator<string>
{
public override string Next(EntityEntry entry)
{
if(entry.Entity is Client clientEntity)
{
return (!String.IsNullOrWhiteSpace(clientEntity.Nickname) ? clientEntity.Nickname : clientEntity.Name) + " (" + clientEntity.Reference + ")";
}
// You need to handle this case here
return "";
}
public override bool GeneratesTemporaryValues => false;
}