Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining a consistent projection in a model with EF6

Background

  • We have a table, let's call it Files.
  • We have certain attributes on the row, such as Name, CreatedDate, etc.
  • We have a blob column with the contents of the file, FileBytes.

So our model looks similar to:

public class FileEntity
{
  public string Name { get; set; }
  public DateTime CreatedDate { get; set; }
  public byte[] FileBytes { get; set; }

  // many other fields, most of which we'd like to use
}

Goal

  • On certain queries, we only care about whether FileBytes is null, not anything about the bytes themselves.
  • We'd like to be able to query and have a field in our model class populated, say, FileHasBytes that is a bool.
  • We'd like this field to exist only in our class, so that we can refer to it in the webapp as part of the model.
  • We'd like to be able to query for this bool value without pulling the full bytes from the field.

Question

How can I, using EF6, define a field on my model class that will be consistently projected, based on another field in the table, without pulling the full contents of that field?

Considered Options / Workarounds

  • Computed column: we were hoping to avoid this because it seems unnecessary
  • View: We'd also like to avoid this because it seems unnecessary to go to this for a single column
  • Projection to a new object: This is doable, but we'd like to be able to map directly without selecting a new object each time, including all of the fields that go with it.
like image 638
SeanKilleen Avatar asked Oct 20 '22 13:10

SeanKilleen


1 Answers

With the current version of EF6 you can't do exactly what you are after.

There are other alternatives, but with all of them you'd have to make compromises on the goals stated above. Such as either using a new projected type with the computed property, or not querying on the computed value and be explicit on the condition instead, etc.

However, using something like DelegateDecompiler it might be possible to have the model and query just as you are expecting.

Something along the lines of:

[Computed]
public bool HasFileBytes
{
    get { return FileBytes != null; }
}

And in your query you'd use the .Decompile() call to get that translated:

var query = ctx.Files
    .Where(x => x.HasFileBytes)
    .Decompile();

Using Linq.Translations could be another similar alternative.

source: http://www.daveaglick.com/posts/computed-properties-and-entity-framework

like image 147
Pablo Romeo Avatar answered Oct 22 '22 03:10

Pablo Romeo