, IsLoaded HandleObjectMaterialized ( ObjectMaterialized) , (. ). , , IsLoaded IsLoaded Self-tracking.
First() ToList(), FirstWithLoaded() ToListWithLoaded(), :
public static T FirstOrDefaultWithLoaded<T>(this IQueryable<T> source) where T : new()
{
T result = default(T);
if (source != null)
{
result = source.FirstOrDefault();
var querySource = source as ObjectQuery<T>;
if (querySource != null)
{
PopulateIsLoaded(result, querySource.Context);
}
}
return result;
}
private static void PopulateIsLoaded(object inputEntity, ObjectContext dataContext)
{
var entry = dataContext.ObjectStateManager.GetObjectStateEntry(inputEntity);
var relationShipManager = GetPropertyValue(entry, "RelationshipManager");
if (relationShipManager != null)
{
var relationships = GetPropertyValue(relationShipManager, "Relationships") as IEnumerable<RelatedEnd>;
if (relationships != null)
{
foreach (RelatedEnd relationship in relationships)
{
var isLoaded = GetRelatedEndPropertyValue(relationship, "IsLoaded");
if (isLoaded != null && (bool)isLoaded)
{
var navigationProperty = GetRelatedEndPropertyValue(relationship, "NavigationProperty");
var identity = GetPropertyValue(navigationProperty, "Identity");
var isLoadedProperty = entry.Entity.GetType().GetProperty(identity + "IsLoaded");
if (isLoadedProperty != null)
{
isLoadedProperty.SetValue(entry.Entity, true, null);
}
}
}
}
}
}
private static object GetPropertyValue(object inputObject, string propertyName)
{
object result = null;
if (inputObject != null)
{
var property = inputObject.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (property != null)
{
result = property.GetValue(inputObject, null);
}
}
return result;
}
private static object GetRelatedEndPropertyValue(RelatedEnd inputObject, string propertyName)
{
object result = null;
if (inputObject != null)
{
PropertyInfo property = null;
property = inputObject.GetType().GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (property != null)
{
result = property.GetValue(inputObject, null);
}
}
return result;
}
, "NavigationProperty", NavigationProperty.Identity, (, Person.Addresses Person.Address). , .
, . T4 IsLoaded , , Person. AddressesIsLoaded :
<#
if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
{
#>
[DataMember]
<#=Accessibility.ForReadOnlyProperty(navProperty)#> bool <#=code.Escape(navProperty)#>IsLoaded
{
get; set;
}
<#
}
#>