/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder) { if (_options?.UseLazyLoadingProxies == true) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { if (entityType.ClrType != null && !entityType.ClrType.IsAbstract) { if (entityType.ClrType.IsSealed) { throw new InvalidOperationException(ProxiesStrings.ItsASeal(entityType.DisplayName())); } var binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; if (binding == null) { _directBindingConvention.Apply(modelBuilder); } binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; entityType[CoreAnnotationNames.ConstructorBinding] = RewriteToFactoryBinding(binding); foreach (var navigation in entityType.GetNavigations()) { if (navigation.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldNavigation(navigation.Name, entityType.DisplayName())); } if (!navigation.PropertyInfo.GetMethod.IsVirtual) { throw new InvalidOperationException( ProxiesStrings.NonVirtualNavigation(navigation.Name, entityType.DisplayName())); } navigation.SetPropertyAccessMode(PropertyAccessMode.Field); } } } } return(modelBuilder); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder) { if (_options?.UseLazyLoadingProxies == true) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { if (entityType.ClrType?.IsAbstract == false) { if (entityType.ClrType.IsSealed) { throw new InvalidOperationException(ProxiesStrings.ItsASeal(entityType.DisplayName())); } var proxyType = _proxyFactory.CreateLazyLoadingProxyType(entityType); foreach (var conflictingProperty in entityType.GetDerivedTypes() .SelectMany(e => e.GetDeclaredServiceProperties().Where(p => p.ClrType == typeof(ILazyLoader))) .ToList()) { conflictingProperty.DeclaringEntityType.RemoveServiceProperty(conflictingProperty.Name); } var serviceProperty = entityType.GetServiceProperties().FirstOrDefault(e => e.ClrType == typeof(ILazyLoader)); if (serviceProperty == null) { serviceProperty = entityType.AddServiceProperty(_lazyLoaderProperty, ConfigurationSource.Convention); serviceProperty.SetParameterBinding( (ServiceParameterBinding) new LazyLoaderParameterBindingFactory().Bind( entityType, typeof(ILazyLoader), nameof(IProxyLazyLoader.LazyLoader))); } var binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; if (binding == null) { _directBindingConvention.Apply(modelBuilder); } binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; entityType[CoreAnnotationNames.ConstructorBinding] = new FactoryMethodConstructorBinding( _proxyFactory, _createLazyLoadingProxyMethod, new List <ParameterBinding> { new EntityTypeParameterBinding(), new DefaultServiceParameterBinding(typeof(ILazyLoader), typeof(ILazyLoader), serviceProperty), new ObjectArrayParameterBinding(binding.ParameterBindings) }, proxyType); foreach (var navigation in entityType.GetNavigations()) { if (navigation.PropertyInfo == null) { throw new InvalidOperationException( ProxiesStrings.FieldNavigation(navigation.Name, entityType.DisplayName())); } if (!navigation.PropertyInfo.GetMethod.IsVirtual) { throw new InvalidOperationException( ProxiesStrings.NonVirtualNavigation(navigation.Name, entityType.DisplayName())); } navigation.SetPropertyAccessMode(PropertyAccessMode.Field); } } } } return(modelBuilder); }
public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder) { if (_options?.UseLazyLoadingProxies == true) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { if (entityType.ClrType != null && !entityType.ClrType.IsAbstract && entityType.GetNavigations().Any(p => p.PropertyInfo.GetMethod.IsVirtual)) { if (entityType.ClrType.IsSealed) { throw new InvalidOperationException($"Entity type '{entityType.DisplayName()}' is sealed. UseLazyLoadingProxies requires all entity types to be public, unsealed, have virtual navigation properties, and have a public or protected constructor."); } var proxyType = _proxyFactory.CreateLazyLoadingProxyType(entityType); var serviceProperty = entityType.GetServiceProperties().FirstOrDefault(e => e.ClrType == typeof(ILazyLoader)); if (serviceProperty == null) { serviceProperty = entityType.AddServiceProperty(_lazyLoaderProperty, ConfigurationSource.Convention); serviceProperty.SetParameterBinding( (ServiceParameterBinding) new LazyLoaderParameterBindingFactory().Bind( entityType, typeof(ILazyLoader), nameof(IProxyLazyLoader.LazyLoader))); } var binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; if (binding == null) { _directBindingConvention.Apply(modelBuilder); } binding = (ConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; entityType[CoreAnnotationNames.ConstructorBinding] = new FactoryMethodConstructorBinding( _proxyFactory, _createLazyLoadingProxyMethod, new List <ParameterBinding> { new EntityTypeParameterBinding(), new DefaultServiceParameterBinding(typeof(ILazyLoader), typeof(ILazyLoader), serviceProperty), new ObjectArrayParameterBinding(binding.ParameterBindings) }, proxyType); foreach (var navigation in entityType.GetNavigations()) { if (navigation.PropertyInfo == null) { throw new InvalidOperationException( $"Navigation property '{navigation.Name}' on entity type '{entityType.DisplayName()}' is mapped without a CLR property. UseLazyLoadingProxies requires all entity types to be public, unsealed, have virtual navigation properties, and have a public or protected constructor."); } if (navigation.PropertyInfo.GetMethod.IsVirtual) { navigation.SetPropertyAccessMode(PropertyAccessMode.Field); } } } } } return(modelBuilder); }