3

I use EF 4.3.1 I need adding a Default Value of an entity at the moment of saving.

At the moment I'm using SaveChanges() and it works.

As you can see from the code I use ChangeTracker.Entries<Option>() where Option rappresent a specifc DataType.

I would like to know if is possible and how to write a more generic version of ChangeTracker.Entries something like ChangeTracker.Entries<t>() so it can check all type of entities in my Model, as you can see in my specif case I have a NoteInternal property on many classes

      public override int SaveChanges()
    {
        #region Option BL
        var entities = ChangeTracker.Entries<Option>()
                                    .Where(e => e.State == EntityState.Added ||
                                                e.State == EntityState.Modified)
                                    .Select(e => e.Entity);
        // Add Default values when Creating or Editing an Entity
        string defaultvalue = "";
        foreach (var entity in entities)
        {
            if (String.IsNullOrWhiteSpace(entity.NoteInternal))
                entity.NoteInternal = defaultvalue;
        }
        #endregion

        return base.SaveChanges();
    }

Thanks for your help!

PS: does it make sense use the DYNAMIC datatype here?

GibboK
  • 71,848
  • 143
  • 435
  • 658

2 Answers2

4

I can think of three options:

  1. Use reflection to check if each item has a NoteInternal property. This is slow.
  2. Use dynamic to try to access the NotIntenral property of each item. You have to check for and handle the exception thrown when the entity does not have the property.
  3. Make an interface IHasNoteInternal that defines the property and have all entities that has the property implement that interface. Then get all entries of IHasNoteInternal type.

I think that the 3. option is best and gives the best design, but it requires you to change the entities which migh or might not be possible. I don't know if you can use the generic Entries<TEntity>() method to get the changed entities - it might fail to match the entities based on an interface. In that case, use the non-generic Entries() and use linq's OfType<T>() operator to filter out the relevant entries.

var hasNotInternal = ChangeTracker.Entries()
                     .Select(e => e.Entity).OfType<IHasNotInternal>();
Anders Abel
  • 67,989
  • 17
  • 150
  • 217
1

Make your entries inherit from an interface that implements a NoteInternal property.

create an extension class

public static class DbChangeTrackerExtensions {
public static IEnumerable<T> TypedEntries<T>(this DbChangeTracker tracker) {
  return tracker.Entries().OfType<T>();
}

Then you can call it passing in this interface.

Or if changing the entities is not possible

var name="NoteInternal";

var entities = ChangeTracker.Entries()  
                                .Where(e => e.State == EntityState.Added ||  
                                            e.State == EntityState.Modified)  
                                .Where(e => e.CurrentValues.Any(c=>c.Name==name && string.IsNullOrWhiteSpace((string)c.CurrentValue)));  
    // Add Default values when Creating or Editing an Entity  
    string defaultvalue = "";  
    foreach (var entity in entities)  
    {  
       entity.Property(name).CurrentValue=defaultvalue;
    }  
Bob Vale
  • 18,094
  • 1
  • 42
  • 49