IsLoaded for self-control objects

I use self-monitoring objects with EF 4.0, and I see that there are no IsLoaded attributes for navigation objects, which are involved in many ways, as they are on standard EF objects. Therefore, if you request an identity and do not include addresses, then an empty list comes for person.Addresses, but there is no way to find out if addresses have been downloaded or the person simply does not have addresses.

Is there any way to find out if the navigation property has been loaded in self-monitoring objects?

And if there is no way to access the current ObjectQuery from the ObjectContext so that I can see what properties the user is trying to extend and create custom IsLoaded properties?

+3
source share
2 answers

, 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)
            {       
                //Call the base FirstOrDefault
                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 relationShipManagerProperty = entryType.GetProperty("RelationshipManager");//.GetValue(entityType, null);
            var relationShipManager = GetPropertyValue(entry, "RelationshipManager");// relationShipManagerProperty.GetValue(entry, null);

            if (relationShipManager != null)
            {
                //get the relationships (this is a sealed property)
                var relationships = GetPropertyValue(relationShipManager, "Relationships") as IEnumerable<RelatedEnd>;

                if (relationships != null)
                {
                    foreach (RelatedEnd relationship in relationships)
                    {
                        //check to see whether the relationship is loaded
                        var isLoaded = GetRelatedEndPropertyValue(relationship, "IsLoaded");

                        if (isLoaded != null && (bool)isLoaded)
                        {
                            //if the relationship is loaded then set the
                            //<NavigationPropertyName>IsLoaded on entry to true
                            var navigationProperty = GetRelatedEndPropertyValue(relationship, "NavigationProperty");
                            var identity = GetPropertyValue(navigationProperty, "Identity");

                            //get the IsLoaded property on entry
                            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)
        {
#>
    //The IsLoaded property for use on the client side when including collections
    [DataMember]
    <#=Accessibility.ForReadOnlyProperty(navProperty)#> bool <#=code.Escape(navProperty)#>IsLoaded
    {
        get; set;
    }
<#
        }
#>
+1

EF4 IsLoaded. . .Load().

, SelfTrackingEntities t4 . , . , t4.

0

Source: https://habr.com/ru/post/1726205/


All Articles