0

I have a class that is mapped using Entity Framework. This class has dozens of fields, and in the database there are millions of rows for this class. The class looks like this

public class MyEntity
{
   public string Key { get; set; }

   public string ImportantField1 { get; set; }
   public string ImportantField2 { get; set; }

   public string AnotherField1 { get; set; }
   public string AnotherField2 { get; set; }
   // ...
   public string AnotherField50 { get; set; }
}

My program creates new instances of this object, assigns values to all the fields, and adds them to the database.

I also have some places in my program where I need to retrieve all objects of this class, do some calculations using all the data, and store those calculations while the program is running. In this situation, I first call a method that retrieves all rows from the database like this:

public class MyEntityService
{
   private MyContext context;

   public List<MyEntity> GetMyEntities()
   {
      return this.context.MyEntities.ToList();   
   }
}

However, I only need the fields Key, ImportantField, and ImportantField2 to do my calculations. So those 50 AdditionalFields that are part of the class are wasting unnecessary network bandwidth and memory in this situation. I would like to only retrieve the 3 fields that I need.

I was considering making a new class called MyEntitySummary which only has the fields Key, ImportantField, and ImportantField2 and mapping that to a new view that I create on my table.

My questions are:

  • Is there a standard practice for handling this situation? If so, what is it?
  • Is making a "summary" class a good design, and is calling it MyEntitySummary a good naming scheme? I'm worried that in the future I might need to do that same thing but using a different subset of MyEntity fields, and then what would I call that second "summary" class?
1

In EF there is built-in technique called table splitting; excerpt from the docs (emphasis mine):

EF Core allows to map two or more entities to a single row. This is called table splitting or table sharing.

Configuration

To use table splitting the entity types need to be mapped to the same table, have the primary keys mapped to the same columns and at least one relationship configured between the primary key of one entity type and another in the same table.

A common scenario for table splitting is using only a subset of the columns in the table for greater performance or encapsulation.

Although, configuring and maintaining partial copy of an entity type may be too much work in some cases, therefore querying directly into a new object is also viable.

As for naming, if you want to avoid collisions, include the use-case in to the name, e.g. MyEntityCatalogSummary or MyEntityReportSummary.

1

Depending on your needs, you could use an anonymous type or a defined type.

var myData = context
                .MyEntities
                .Select(x => new 
                    { 
                        Key = x.Key, 
                        ImportantField1 = x.ImportantField1, 
                        ImportantField2 = x.ImportantField2
                    })
                 .ToList();

But if this data is meant to be exposed beyond your class, it's advised to define a specific type so it is better documented.

public class MyEntitySummary
{
   public string Key { get; set; }
   public string ImportantField1 { get; set; }
   public string ImportantField2 { get; set; }
}

The logic remains mostly the same:

var myData = context
                .MyEntities
                .Select(x => new MyEntitySummary()
                    { 
                        Key = x.Key, 
                        ImportantField1 = x.ImportantField1, 
                        ImportantField2 = x.ImportantField2
                    })
                 .ToList();

Note: whether you use a constructor or object initialization is up to you.

Is making a "summary" class a good design, and is calling it MyEntitySummary a good naming scheme? I'm worried that in the future I might need to do that same thing but using a different subset of MyEntity fields, and then what would I call that second "summary" class?

Naming is subjective to your use case.

Since you're going to deal with several specific subsets, I suggest either naming them after the commonality of the data (e.g. MyEntityPersonalDetails vs MyEntityAuditData), or the specific use cases for the types (e.g.MyEntityMobileDetail vs MyEntityEmailData)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.