private static Func <object, IEntityWrapper> CreateWrapperDelegate(Type entityType) { // For entities that implement all our interfaces we create a special lightweight wrapper that is both // smaller and faster than the strategy-based wrapper. // Otherwise, the wrapper is provided with different delegates depending on which interfaces are implemented. bool isIEntityWithRelationships = typeof(IEntityWithRelationships).IsAssignableFrom(entityType); bool isIEntityWithChangeTracker = typeof(IEntityWithChangeTracker).IsAssignableFrom(entityType); bool isIEntityWithKey = typeof(IEntityWithKey).IsAssignableFrom(entityType); bool isProxy = EntityProxyFactory.IsProxyType(entityType); MethodInfo createDelegate; if (isIEntityWithRelationships && isIEntityWithChangeTracker && isIEntityWithKey && !isProxy) { createDelegate = typeof(EntityWrapperFactory).GetMethod("CreateWrapperDelegateTypedLightweight", BindingFlags.NonPublic | BindingFlags.Static); } else if (isIEntityWithRelationships) { // This type of strategy wrapper is used when the entity implements IEntityWithRelationships // In this case it is important that the entity itself is used to create the RelationshipManager createDelegate = typeof(EntityWrapperFactory).GetMethod("CreateWrapperDelegateTypedWithRelationships", BindingFlags.NonPublic | BindingFlags.Static); } else { createDelegate = typeof(EntityWrapperFactory).GetMethod("CreateWrapperDelegateTypedWithoutRelationships", BindingFlags.NonPublic | BindingFlags.Static); } createDelegate = createDelegate.MakeGenericMethod(entityType); return((Func <object, IEntityWrapper>)createDelegate.Invoke(null, new object[0])); }
internal static Type GetEntityIdentityType(Type entityType) { if (!EntityProxyFactory.IsProxyType(entityType)) { return(entityType); } return(entityType.BaseType()); }
/// <summary> /// Constructs a wrapper for the given entity. /// Note: use EntityWrapperFactory instead of calling this constructor directly. /// </summary> /// <param name="entity">The entity to wrap</param> internal LightweightEntityWrapper(TEntity entity) : base(entity, entity.RelationshipManager) { Debug.Assert(entity is IEntityWithChangeTracker, "LightweightEntityWrapper only works with entities that implement IEntityWithChangeTracker"); Debug.Assert(entity is IEntityWithRelationships, "LightweightEntityWrapper only works with entities that implement IEntityWithRelationships"); Debug.Assert(entity is IEntityWithKey, "LightweightEntityWrapper only works with entities that implement IEntityWithKey"); Debug.Assert(!EntityProxyFactory.IsProxyType(entity.GetType()), "LightweightEntityWrapper only works with entities that are not proxies"); _entity = entity; }
/// <summary> /// Constructs a wrapper as part of the materialization process. This constructor is only used /// during materialization where it is known that the entity being wrapped is newly constructed. /// This means that some checks are not performed that might be needed when thw wrapper is /// created at other times, and information such as the identity type is passed in because /// it is readily available in the materializer. /// </summary> /// <param name="entity">The entity to wrap</param> /// <param name="key">The key for the entity</param> /// <param name="entitySet">The entity set, or null if none is known</param> /// <param name="context">The context to which the entity should be attached</param> /// <param name="mergeOption">NoTracking for non-tracked entities, AppendOnly otherwise</param> /// <param name="identityType">The type of the entity ignoring any possible proxy type</param> internal LightweightEntityWrapper(TEntity entity, EntityKey key, EntitySet entitySet, ObjectContext context, MergeOption mergeOption, Type identityType) : base(entity, entity.RelationshipManager, entitySet, context, mergeOption, identityType) { Debug.Assert(entity is IEntityWithChangeTracker, "LightweightEntityWrapper only works with entities that implement IEntityWithChangeTracker"); Debug.Assert(entity is IEntityWithRelationships, "LightweightEntityWrapper only works with entities that implement IEntityWithRelationships"); Debug.Assert(entity is IEntityWithKey, "LightweightEntityWrapper only works with entities that implement IEntityWithKey"); Debug.Assert(!EntityProxyFactory.IsProxyType(entity.GetType()), "LightweightEntityWrapper only works with entities that are not proxies"); _entity = entity; _entity.EntityKey = key; }
// Creates delegates that create strategy objects appropriate for the type of entity. private static void CreateStrategies <TEntity>(out Func <object, IPropertyAccessorStrategy> createPropertyAccessorStrategy, out Func <object, IChangeTrackingStrategy> createChangeTrackingStrategy, out Func <object, IEntityKeyStrategy> createKeyStrategy) { Type entityType = typeof(TEntity); bool isIEntityWithRelationships = typeof(IEntityWithRelationships).IsAssignableFrom(entityType); bool isIEntityWithChangeTracker = typeof(IEntityWithChangeTracker).IsAssignableFrom(entityType); bool isIEntityWithKey = typeof(IEntityWithKey).IsAssignableFrom(entityType); bool isProxy = EntityProxyFactory.IsProxyType(entityType); if (!isIEntityWithRelationships || isProxy) { createPropertyAccessorStrategy = GetPocoPropertyAccessorStrategyFunc(); } else { createPropertyAccessorStrategy = GetNullPropertyAccessorStrategyFunc(); } if (isIEntityWithChangeTracker) { createChangeTrackingStrategy = GetEntityWithChangeTrackerStrategyFunc(); } else { createChangeTrackingStrategy = GetSnapshotChangeTrackingStrategyFunc(); } if (isIEntityWithKey) { createKeyStrategy = GetEntityWithKeyStrategyStrategyFunc(); } else { createKeyStrategy = GetPocoEntityKeyStrategyFunc(); } }
/// <summary> /// Returns the Type object that should be used to identify the type in the o-space /// metadata. This is normally just the type that is passed in, but if the type /// is a proxy that we have generated, then its base type is returned instead. /// This ensures that both proxy entities and normal entities are treated as the /// same kind of entity in the metadata and places where the metadata is used. /// </summary> internal static Type GetEntityIdentityType(Type entityType) { return(EntityProxyFactory.IsProxyType(entityType) ? entityType.BaseType : entityType); }