On a project using the Entity Framework (3.5 SP1), I was tasked with only sending “changed” or “added” values to a back-end system to keep network traffic down. After a lot of research and testing, I came up with the solution below.
Use this code below:
private static void FindChangedEntityProperties<T>(LocalEntityState state,
ClientDataEntities context,
ref IEnumerable<string> props,
ref ObjectStateEntry ose)
{
if (state == LocalEntityState.Modified)
{
ose = context.ObjectStateManager.GetObjectStateEntries<T>(
EntityState.Modified)
.FirstOrDefault();
if (ose != null)
{
props = ose.GetModifiedProperties();
}
}
else
{
ose = context.ObjectStateManager.GetObjectStateEntries<T>(EntityState.Added |
EntityState.Modified
).FirstOrDefault();
if (ose == null)
{
return;
}
else
{
var stateEntry = context.ObjectStateManager.GetObjectStateEntry(ose.Entity);
props = (from
fm in stateEntry.CurrentValues.DataRecordInfo.FieldMetadata
where
stateEntry.CurrentValues.IsDBNull(fm.Ordinal) == false
select
fm.FieldType.Name
).ToArray();
}
}
//Sort (helps with switch statements)
if (props != null && props.Count() > 0)
{
props = props.OrderBy(p => p.ToUpper());
}
}
Add this extension method:
public static IEnumerable<ObjectStateEntry> GetObjectStateEntries<TEntity>(this
ObjectStateManager osm,
EntityState state)
{
return from
entry in osm.GetObjectStateEntries(state)
where
entry.Entity is TEntity
select
entry;
}
Usage:
IEnumerable<string> pp = null;
ObjectStateEntry pState = null;
FindEntityPropertiesToReport<Person>(p.EntityState, context, ref jp, ref pState);
if (pp != null && pp.Count() > 0)
{
foreach (var propName in pp)
{
//Example of pulling out a DateTime property
var changedProp = pState.CurrentValues.GetDateTime(pState.CurrentValues
.GetOrdinal(propName));
}
}
Tip By: David McCarter
Discover more from dotNetTips.com
Subscribe to get the latest posts sent to your email.
