protected virtual void ValidateNonKeyValueGeneration([NotNull] IModel model) { foreach (var property in model.GetEntityTypes() .SelectMany(t => t.GetDeclaredProperties()) .Where( p => ((JetPropertyAnnotations)p.Jet()).GetJetValueGenerationStrategy(fallbackToModel: false) == JetValueGenerationStrategy.SequenceHiLo && !p.IsKey())) { throw new InvalidOperationException( JetStrings.NonKeyValueGeneration(property.Name, property.DeclaringEntityType.DisplayName())); } }
protected override void ValidateSharedColumnsCompatibility(IReadOnlyList <IEntityType> mappedTypes, string tableName) { base.ValidateSharedColumnsCompatibility(mappedTypes, tableName); var identityColumns = EnumerableExtensions.Distinct(mappedTypes.SelectMany(et => et.GetDeclaredProperties()) .Where(p => p.Jet().ValueGenerationStrategy == JetValueGenerationStrategy.IdentityColumn), (p1, p2) => p1.Name == p2.Name) .ToList(); if (identityColumns.Count > 1) { var sb = new StringBuilder() .AppendJoin(identityColumns.Select(p => "'" + p.DeclaringEntityType.DisplayName() + "." + p.Name + "'")); throw new InvalidOperationException(JetStrings.MultipleIdentityColumns(sb, tableName)); } }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> protected override void ValidateSharedColumnsCompatibility( IReadOnlyList <IEntityType> mappedTypes, string tableName, IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger) { base.ValidateSharedColumnsCompatibility(mappedTypes, tableName, logger); var identityColumns = new List <IProperty>(); var propertyMappings = new Dictionary <string, IProperty>(); foreach (var property in mappedTypes.SelectMany(et => et.GetDeclaredProperties())) { var columnName = property.GetColumnName(); if (propertyMappings.TryGetValue(columnName, out var duplicateProperty)) { var propertyStrategy = property.GetValueGenerationStrategy(); var duplicatePropertyStrategy = duplicateProperty.GetValueGenerationStrategy(); if (propertyStrategy != duplicatePropertyStrategy && (propertyStrategy == JetValueGenerationStrategy.IdentityColumn || duplicatePropertyStrategy == JetValueGenerationStrategy.IdentityColumn)) { throw new InvalidOperationException( JetStrings.DuplicateColumnNameValueGenerationStrategyMismatch( duplicateProperty.DeclaringEntityType.DisplayName(), duplicateProperty.Name, property.DeclaringEntityType.DisplayName(), property.Name, columnName, tableName)); } } else { propertyMappings[columnName] = property; if (property.GetValueGenerationStrategy() == JetValueGenerationStrategy.IdentityColumn) { identityColumns.Add(property); } } } if (identityColumns.Count > 1) { var sb = new StringBuilder() .AppendJoin(identityColumns.Select(p => "'" + p.DeclaringEntityType.DisplayName() + "." + p.Name + "'")); throw new InvalidOperationException(JetStrings.MultipleIdentityColumns(sb, tableName)); } }
protected override void ValidateSharedTableCompatibility( IReadOnlyList <IEntityType> mappedTypes, string tableName) { var firstMappedType = mappedTypes[0]; var isMemoryOptimized = firstMappedType.Jet().IsMemoryOptimized; foreach (var otherMappedType in mappedTypes.Skip(1)) { if (isMemoryOptimized != otherMappedType.Jet().IsMemoryOptimized) { throw new InvalidOperationException( JetStrings.IncompatibleTableMemoryOptimizedMismatch( tableName, firstMappedType.DisplayName(), otherMappedType.DisplayName(), isMemoryOptimized ? firstMappedType.DisplayName() : otherMappedType.DisplayName(), !isMemoryOptimized ? firstMappedType.DisplayName() : otherMappedType.DisplayName())); } } base.ValidateSharedTableCompatibility(mappedTypes, tableName); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> protected virtual void ValidateIndexIncludeProperties( [NotNull] IModel model, [NotNull] IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger) { foreach (var index in model.GetEntityTypes().SelectMany(t => t.GetDeclaredIndexes())) { var includeProperties = index.GetIncludeProperties(); if (includeProperties?.Count > 0) { var notFound = includeProperties .FirstOrDefault(i => index.DeclaringEntityType.FindProperty(i) == null); if (notFound != null) { throw new InvalidOperationException( JetStrings.IncludePropertyNotFound(index.DeclaringEntityType.DisplayName(), notFound)); } var duplicate = includeProperties .GroupBy(i => i) .Where(g => g.Count() > 1) .Select(y => y.Key) .FirstOrDefault(); if (duplicate != null) { throw new InvalidOperationException( JetStrings.IncludePropertyDuplicated(index.DeclaringEntityType.DisplayName(), duplicate)); } var inIndex = includeProperties .FirstOrDefault(i => index.Properties.Any(p => i == p.Name)); if (inIndex != null) { throw new InvalidOperationException( JetStrings.IncludePropertyInIndex(index.DeclaringEntityType.DisplayName(), inIndex)); } } } }