Stuck trying to make a helper method to Save DB changes with catching

c# entity-framework entity-framework-6

Question

I'm working on a project with a C# MVC using Entity Framework 6.0 and I have a bunch of models like Customer, Promotion, Messages, and in all of them, I'm pretty space inefficient with repetitive error handling logic. For example, here's how I'm saving new customer records.

Note the length error checking!

public class CustomerRepository : IRepository<Customer>

   {

       private MyDBEntities db = new MyDBEntities();

       public uniqueIdentifier AddRecord (Customer record) {
           record.PromotionStatus = CheckForPromo(record);
           record.LastOrderID = GetLastOrderID(record);

           db.Customer.Add(record);

           try {db.SaveChanges();}
           catch (DbEntityValidationException e){
               foreach (var err in e.EntityValidationErrors){
                   Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following errors", err.Entry.Entity.GetType().Name, err.Entry.State);

                   foreach (var innerErr in err.ValidationErrors){
                       Console.WriteLine("--Property of \"{0}\"  has error \"{1}\"" , innerErr.PropertyName, innerErr.ErrorMessage);
                   }
               }
           }
           return record.id;
       }//end of AddRecord 

   }    

I have a couple different classes modeled in EF and in my tables, like so:

  • Customer
  • Promotions
  • Messages

Each of them has a very similar looking save block like this:

       db.Customer.Add(record);

       try {db.SaveChanges();}
       catch (DbEntityValidationException e){
           foreach (var err in e.EntityValidationErrors){
               Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following errors", err.Entry.Entity.GetType().Name, err.Entry.State);

               foreach (var innerErr in err.ValidationErrors){
                   Console.WriteLine("--Property of \"{0}\"  has error \"{1}\"" , innerErr.PropertyName, innerErr.ErrorMessage);
               }
           }
       }

The only thing different between them is whether it is db.Customer.Add(record);, or db.Promotion.Add(record); or so on.

I thought I could add a new method to my repo like this

private void TrySaveRecord(string recordType, object record){
       db.recordType.Add(record);

       try {db.SaveChanges();}
           catch (DbEntityValidationException e){
               foreach (var err in e.EntityValidationErrors){
                   Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following errors", err.Entry.Entity.GetType().Name, err.Entry.State);

                   foreach (var innerErr in err.ValidationErrors){
                       Console.WriteLine("--Property of \"{0}\"  has error \"{1}\"" , innerErr.PropertyName, innerErr.ErrorMessage);
                   }
               }
           }

   }

But I ran into an issue of MyDbEntities does not contain a definition for 'recordType'. Since then I've been spiraling around a whirlpool of depression, feels like this is probably doable but I don't know the vocabulary for this domain to figure out how to describe what I'm trying to do.

Thanks for any pointers :)

1
2
12/3/2018 6:21:36 PM

Accepted Answer

There are several ways you can handle it.

The most obvious is to let Add outside from the helper method and handle only the SaveChanges.

Another way is to make your helper method generic and use Set<T>() method to access the associated DbSet:

private void TrySaveRecord<T>(T record)
    where T : class
{

    db.Set<T>().Add(record);
    // ...

Another way is to use GetType() and the non generic Set(Type) method:

private void TrySaveRecord(object record)
{

    db.Set(record.GetType()).Add(record);
    // ...

or similar, but using Entry(object) method and setting the State to EntityState.Added (which in EF6 is the same as calling DbSet.Add method):

private void TrySaveRecord(object record)
{

    db.Entry(record).State = EntityState.Added;
    // ...
2
12/3/2018 6:08:15 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow