Force Loading of all Related Entities within Entity without knowing Entity Class Types
I'm trying to serialize an entity and all its related entities for storing as xml before physically deleting the entity (leaving an audit trail).
I'm using a DataContractSerializer
which seems to be getting around the shallow serialization performed when using an XmlSerializer
.
The only trouble is that only related entities that have been loaded get serialized.
I've tried to create a helper function that will take any entity and iterate though its properties looking for related entities to load, however its failing on EntityCollection
properties because I can't cast them to EntityCollection<EntityObject>
. I was trying to use EntityObject
as I figured polymorphism would come to my aid, but the property won't cast complaining it's a different type.
Any ideas?
/// <summary>
/// Forces loading of all related entities.
/// </summary>
/// <param name="processed">Processed entities, used to prevent infinite looping.</param>
private static void LoadAllRelatedEntities(EntityObject entity, List<EntityKey> processed)
{
// Check we haven't already processed this entity
foreach (EntityKey key in processed)
{
if (entity.EntityKey == key)
return; // Exit without doing anything more with this entity
}
processed.Add(entity.En开发者_如何学JAVAtityKey);
// Pull in all child entities
foreach (PropertyInfo p in entity.GetType().GetProperties())
{
if (p.PropertyType == typeof(EntityReference) || p.PropertyType.BaseType == typeof(EntityReference))
{
if (p.GetValue(entity, null) != null)
{
EntityReference e = (EntityReference)p.GetValue(entity, null);
if (!e.IsLoaded)
e.Load();
// Load child entities
IEnumerator eEnum = e.GetEnumerator();
while (eEnum.MoveNext())
{
LoadAllRelatedEntities((EntityObject)eEnum.Current, processed);
}
}
}
else if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>))
{
EntityCollection<EntityObject> e = (EntityCollection<EntityObject>)p.GetValue(entity, null);
if (!e.IsLoaded)
e.Load();
// Load child entities
IEnumerator eEnum = e.GetEnumerator();
while (eEnum.MoveNext())
{
LoadAllRelatedEntities((EntityObject)eEnum.Current, processed);
}
}
}
}
I found a solution that did what I want:
else if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>))
{
IEnumerable pEnum = (IEnumerable)p.GetValue(entity, null);
IRelatedEnd pEnd = (IRelatedEnd)p.GetValue(entity, null);
pEnd.Load();
// Load child entities
IEnumerator eEnum = pEnum.GetEnumerator();
while (eEnum.MoveNext())
{
LoadAllRelatedEntities((EntityObject)eEnum.Current, ref processed);
}
}
I also needed to change the processed
param to a ref so it worked as required:
LoadAllRelatedEntities(EntityObject entity, ref List<EntityKey> processed)
In my case I also had to add some filtering to which entities I would load as in my case a lot were self-referencing somewhere down the chain and so caused endless looping.
精彩评论