protected virtual bool SetDefaultValue(object value) { if (value != null) { var valueType = value.GetType(); if (Property.ClrType.UnwrapNullableType() != valueType) { try { value = Convert.ChangeType(value, Property.ClrType, CultureInfo.InvariantCulture); } catch (Exception) { throw new InvalidOperationException(ResX.IncorrectDefaultValueType(value, valueType, Property.Name, Property.ClrType, Property.DeclaringEntity.Name)); } } if (valueType.GetTypeInfo().IsEnum) { value = Convert.ChangeType(value, valueType.UnwrapEnumType(), CultureInfo.InvariantCulture); } } if (!ShouldThrowOnConflict && DefaultValue != value && value != null) { ClearAllServerGeneratedValues(); } Metadata[RelationalAnnotationNames.DefaultValue] = value; return(true); }
public static bool AreCompatible(IReadOnlyList <Property> principalProperties, IReadOnlyList <Property> dependentProperties, Entity principalEntity, Entity dependentEntity, bool shouldThrow) { Check.NotNull(principalProperties, nameof(principalProperties)); Check.NotNull(dependentProperties, nameof(dependentProperties)); Check.NotNull(principalEntity, nameof(principalEntity)); Check.NotNull(dependentEntity, nameof(dependentEntity)); if (!ArePropertyCountsEqual(principalProperties, dependentProperties)) { if (shouldThrow) { throw new InvalidOperationException(ResX.ForeignKeyCountMismatch(Property.Format(dependentProperties), dependentEntity.Name, Property.Format(principalProperties), principalEntity.Name)); } return(false); } if (!ArePropertyTypesCompatible(principalProperties, dependentProperties)) { if (shouldThrow) { throw new InvalidOperationException(ResX.ForeignKeyTypeMismatch(Property.Format(dependentProperties), dependentEntity.Name, Property.Format(principalProperties), principalEntity.Name)); } return(false); } return(true); }
protected virtual bool CanSetDefaultValueSql(string value) { if (DefaultValueSql == value) { return(true); } if (ShouldThrowOnConflict) { if (DefaultValue != null) { throw new InvalidOperationException(ResX.ConflictingColumnServerGeneration(nameof(DefaultValueSql), Property.Name, nameof(DefaultValue))); } if (ComputedColumnSql != null) { throw new InvalidOperationException(ResX.ConflictingColumnServerGeneration(nameof(DefaultValueSql), Property.Name, nameof(ComputedColumnSql))); } } else if (value != null && (!CanSetDefaultValue(null) || !CanSetComputedColumnSql(null))) { return(false); } return(true); }
/// <summary> /// Sets the primary key for this entity. /// </summary> /// <param name="properties"> The properties that make up the primary key. </param> /// <returns> The newly created key. </returns> internal Key SetPrimaryKey(IReadOnlyList <Property> properties) { Check.NotEmpty(properties, nameof(properties)); Check.HasNoNulls(properties, nameof(properties)); if (_baseType != null) { throw new InvalidOperationException(ResX.DerivedEntityKey(Name, _baseType.Name)); } if (_primaryKey != null) { throw new InvalidOperationException(ResX.PrimaryKeyAlreadyExists); } Key key = GetOrAddKey(properties); foreach (var property in key.Properties) { _properties.Remove(property.Name); property.PrimaryKey = key; } _primaryKey = key; foreach (var property in key.Properties) { _properties.Add(property.Name, property); } return(_primaryKey); }
internal Navigation AddNavigation(PropertyInfo navigationProperty, ForeignKey fkToLinkedEntity, ForeignKey fkToTargetedEntity) { Check.NotNull(navigationProperty, nameof(navigationProperty)); Check.NotNull(fkToLinkedEntity, nameof(fkToLinkedEntity)); Check.NotNull(fkToTargetedEntity, nameof(fkToTargetedEntity)); var name = navigationProperty.Name; var duplicateNavigation = FindNavigationsInHierarchy(name).FirstOrDefault(); if (duplicateNavigation != null) { throw new InvalidOperationException(ResX.DuplicateNavigation(name, Name, duplicateNavigation.DeclaringEntity.Name)); } var duplicateProperty = FindPropertiesInHierarchy(name).FirstOrDefault(); if (duplicateProperty != null) { throw new InvalidOperationException(ResX.ConflictingProperty(name, Name, duplicateProperty.DeclaringEntity.Name)); } var navigation = new Navigation(navigationProperty, fkToLinkedEntity, fkToTargetedEntity); _navigations.Add(name, navigation); return(navigation); }
/// <summary> /// <para> /// Add a shadow entity to this model used to represent a many to many association between two entities. /// </para> /// <para> /// Add PK /// Add FK targeting <paramref name="entity1"/> /// Add FK targeting <paramref name="entity2"/> . /// </para> /// </summary> /// <param name="name"> The name of the entity to be added. </param> /// <param name="entity1"> Declaring entity </param> /// <param name="entity2"> Targeting entity </param> /// <returns> The new entity. </returns> internal Entity AddLinkedEntity(string name, Entity entity1, Entity entity2) { Check.NotEmpty(name, nameof(name)); Check.NotNull(entity1, nameof(entity1)); Check.NotNull(entity2, nameof(entity2)); if (FindEntity(name) != null) { throw new InvalidOperationException(ResX.DuplicateEntity(name)); } var linkedEntity = AddEntity(name, runConventions: false); Func <Entity, List <Property> > addPropertiesToLinkedEntity = (entity) => { var properties = new List <Property>(); entity.FindPrimaryKey().Properties.ToList().ForEach(x => { string propertyName = x.Name.Equals("Id", StringComparison.OrdinalIgnoreCase) ? "Id" + x.DeclaringEntity.Name : x.Name; properties.Add(linkedEntity.AddProperty(x.Clone(linkedEntity, propertyName))); }); return(properties); }; var propertiesFromEntity1 = addPropertiesToLinkedEntity(entity1); var propertiesFromEntity2 = addPropertiesToLinkedEntity(entity2); var linkedEntityProperties = propertiesFromEntity1.Concat(propertiesFromEntity2).ToList(); linkedEntity.SetPrimaryKey(linkedEntityProperties); linkedEntity.AddForeignKey(propertiesFromEntity1, entity1.FindPrimaryKey(), entity1); linkedEntity.AddForeignKey(propertiesFromEntity2, entity2.FindPrimaryKey(), entity2); return(linkedEntity); }
public override int GetHashCode() { if (HashCode == 0) { HashCode = ResX.GetHashCode(); } return(HashCode); }
/// <summary> /// Adds a new alternate key to this entity type. /// </summary> /// <param name="properties"> The properties that make up the alternate key. </param> /// <returns> The newly created key. </returns> internal Key AddKey(IReadOnlyList <Property> properties) { Check.NotEmpty(properties, nameof(properties)); Check.HasNoNulls(properties, nameof(properties)); if (_baseType != null) { throw new InvalidOperationException(ResX.DerivedEntityKey(Name, _baseType.Name)); } foreach (var property in properties) { if (FindProperty(property.Name) != property) { throw new InvalidOperationException(ResX.KeyPropertiesWrongEntity(Property.Format(properties), Name)); } if (property.ForeignKeys != null && property.ForeignKeys.Any(k => k.DeclaringEntity != this)) { throw new InvalidOperationException(ResX.KeyPropertyInForeignKey(property.Name, Name)); } if (property.IsNullable) { throw new InvalidOperationException(ResX.NullableKey(Name, property.Name)); } } var key = FindKey(properties); if (key != null) { throw new InvalidOperationException(ResX.DuplicateKey(Property.Format(properties), Name, key.DeclaringEntity.Name)); } key = new Key(properties); _keys.Add(properties, key); foreach (var property in properties) { var currentKeys = property.Keys; if (currentKeys == null) { property.Keys = new Key[] { key }; } else { var newKeys = currentKeys.ToList(); newKeys.Add(key); property.Keys = newKeys; } } return(Model.ConventionDispatcher.OnKeyAdded(key)); }
public static string NullButNotEmpty(string value, string parameterName) { if (!ReferenceEquals(value, null) && (value.Length == 0)) { NotEmpty(parameterName, nameof(parameterName)); throw new ArgumentException(ResX.ArgumentIsEmpty(parameterName)); } return(value); }
public static T NotNull <T>(T value, string parameterName, string propertyName) { if (ReferenceEquals(value, null)) { NotEmpty(parameterName, nameof(parameterName)); NotEmpty(propertyName, nameof(propertyName)); throw new ArgumentException(ResX.ArgumentPropertyNull(propertyName, parameterName)); } return(value); }
/// <summary> /// Adds an annotation to this object. Throws if an annotation with the specified name already exists. /// </summary> /// <param name="name"> The key of the annotation to be added. </param> /// <param name="annotation"> The annotation to be added. </param> /// <returns> The added annotation. </returns> public virtual Annotation AddAnnotation(string name, Annotation annotation) { var previousLength = _annotations.Value.Count; SetAnnotation(name, annotation); if (previousLength == _annotations.Value.Count) { throw new InvalidOperationException(ResX.DuplicateAnnotation(name)); } return(annotation); }
/// <summary> /// Gets the mapping that represents the given database type, throwing if no mapping is found. /// </summary> /// <param name="typeMapper"> The type mapper. </param> /// <param name="typeName"> The type to get the mapping for. </param> /// <returns> The type mapping to be used. </returns> public RelationalTypeMapping GetMapping(string typeName) { Check.NotNull(typeName, nameof(typeName)); var mapping = FindMapping(typeName); if (mapping != null) { return(mapping); } throw new InvalidOperationException(ResX.UnsupportedType(typeName)); }
/// <summary> /// Gets the relational database type for a given .NET type, throwing if no mapping is found. /// </summary> /// <param name="typeMapper"> The type mapper. </param> /// <param name="clrType"> The type to get the mapping for. </param> /// <returns> The type mapping to be used. </returns> public RelationalTypeMapping GetMapping(Type clrType) { Check.NotNull(clrType, nameof(clrType)); var mapping = FindMapping(clrType); if (mapping != null) { return(mapping); } throw new InvalidOperationException(ResX.UnsupportedType(clrType.ShortDisplayName())); }
/// <summary> /// Gets the relational database type for a given property, throwing if no mapping is found. /// </summary> /// <param name="typeMapper"> The type mapper. </param> /// <param name="property"> The property to get the mapping for. </param> /// <returns> The type mapping to be used. </returns> public RelationalTypeMapping GetMapping(Property property) { Check.NotNull(property, nameof(property)); var mapping = FindMapping(property); if (mapping != null) { return(mapping); } throw new InvalidOperationException(ResX.UnsupportedPropertyType(property.DeclaringEntity.Name, property.Name, property.ClrType.ShortDisplayName())); }
public static IReadOnlyList <T> NotEmpty <T>(IReadOnlyList <T> value, string parameterName) { NotNull(value, parameterName); if (value.Count == 0) { NotEmpty(parameterName, nameof(parameterName)); throw new ArgumentException(ResX.CollectionArgumentIsEmpty(parameterName)); } return(value); }
public ForeignKey(IReadOnlyList <Property> dependentProperties, Key principalKey, Entity dependentEntity, Entity principalEntity) { Check.NotEmpty(dependentProperties, nameof(dependentProperties)); Check.HasNoNulls(dependentProperties, nameof(dependentProperties)); Check.NotNull(principalKey, nameof(principalKey)); Check.NotNull(principalEntity, nameof(principalEntity)); Properties = dependentProperties; PrincipalKey = principalKey; DeclaringEntity = dependentEntity; PrincipalEntity = principalEntity; AreCompatible(principalKey.Properties, dependentProperties, principalEntity, dependentEntity, shouldThrow: true); if (!principalEntity.GetKeys().Contains(principalKey)) { throw new InvalidOperationException(ResX.ForeignKeyReferencedEntityKeyMismatch(Property.Format(principalKey.Properties), principalEntity.Name)); } }
private DbCommand CreateCommand(IRelationalConnection connection, IReadOnlyDictionary <string, object> parameterValues) { var command = connection.DbConnection.CreateCommand(); command.CommandText = CommandText; if (connection.CurrentTransaction != null) { command.Transaction = connection.CurrentTransaction.GetDbTransaction(); } if (connection.CommandTimeout != null) { command.CommandTimeout = (int)connection.CommandTimeout; } if (Parameters.Count > 0) { if (parameterValues == null) { throw new InvalidOperationException(ResX.MissingParameterValue(Parameters[0].InvariantName)); } foreach (var parameter in Parameters) { object parameterValue; if (parameterValues.TryGetValue(parameter.InvariantName, out parameterValue)) { parameter.AddDbParameter(command, parameterValue); } else { throw new InvalidOperationException(ResX.MissingParameterValue(parameter.InvariantName)); } } } return(command); }
public static string NotEmpty(string value, string parameterName) { Exception e = null; if (ReferenceEquals(value, null)) { e = new ArgumentNullException(parameterName); } else if (value.Trim().Length == 0) { e = new ArgumentException(ResX.ArgumentIsEmpty(parameterName)); } if (e != null) { NotEmpty(parameterName, nameof(parameterName)); throw e; } return(value); }
public static void LogCommandExecuted(this ILogger logger, DbCommand command, long startTimestamp, long currentTimestamp) { Check.NotNull(logger, nameof(logger)); Check.NotNull(command, nameof(command)); if (logger.IsEnabled(LogLevel.Information)) { var logParameterValues = command.Parameters.Count > 0; var parameters = command.Parameters.Cast <DbParameter>().Select(p => new DbParameterLogData(p.ParameterName, logParameterValues ? p.Value : "?", logParameterValues, p.Direction, p.DbType, p.IsNullable, p.Size, p.Precision, p.Scale)).ToList(); var logData = new DbCommandLogData(command.CommandText.TrimEnd(), command.CommandType, command.CommandTimeout, parameters, DeriveTimespan(startTimestamp, currentTimestamp)); logger.Log(LogLevel.Information, (int)RelationalEventId.ExecutedCommand, logData, null, (state, _) => { var elapsedMilliseconds = DeriveTimespan(startTimestamp, currentTimestamp); return(ResX.RelationalLoggerExecutedCommand(string.Format(CultureInfo.InvariantCulture, "{0:N0}", elapsedMilliseconds), state.Parameters.Select(p => $"{p.Name}={p.FormatParameter()}").Join(), // Interpolation okay here because value is always a string. state.CommandType, state.CommandTimeout, Environment.NewLine, state.CommandText)); }); } }
public virtual void AddDbParameter(DbCommand command, object value) { Check.NotNull(command, nameof(command)); Check.NotNull(value, nameof(value)); var innerValues = value as object[]; if (innerValues != null) { if (innerValues.Length < RelationalParameters.Count) { throw new InvalidOperationException(ResX.MissingParameterValue(RelationalParameters[innerValues.Length].InvariantName)); } for (var i = 0; i < RelationalParameters.Count; i++) { RelationalParameters[i].AddDbParameter(command, innerValues[i]); } } else { throw new InvalidOperationException(ResX.ParameterNotObjectArray(InvariantName)); } }
/// <summary> /// Adds a new relationship to this entity. /// </summary> /// <param name="properties"> The properties that the foreign key is defined on. </param> /// <param name="principalKey"> The primary or alternate key that is referenced. </param> /// <param name="principalEntity"> /// The entity type that the relationship targets. This may be different from the type that <paramref name="principalKey" /> /// is defined on when the relationship targets a derived type in an inheritance hierarchy (since the key is defined on the /// base type of the hierarchy). /// </param> /// <returns> The newly created foreign key. </returns> internal ForeignKey AddForeignKey(IReadOnlyList <Property> properties, Key principalKey, Entity principalEntity, bool runConventions = true) { Check.NotEmpty(properties, nameof(properties)); Check.HasNoNulls(properties, nameof(properties)); Check.NotNull(principalKey, nameof(principalKey)); Check.NotNull(principalEntity, nameof(principalEntity)); foreach (var property in properties) { var actualProperty = FindProperty(property.Name); if (actualProperty == null || !actualProperty.DeclaringEntity.IsAssignableFrom(property.DeclaringEntity)) { throw new InvalidOperationException(ResX.ForeignKeyPropertiesWrongEntity(Property.Format(properties), Name)); } if (actualProperty.GetContainingKeys().Any(k => k.DeclaringEntity != this)) { throw new InvalidOperationException(ResX.ForeignKeyPropertyInKey(actualProperty.Name, Name)); } } var duplicateForeignKey = FindForeignKeysInHierarchy(properties, principalKey, principalEntity).FirstOrDefault(); if (duplicateForeignKey != null) { throw new InvalidOperationException(ResX.DuplicateForeignKey(Property.Format(properties), Name, duplicateForeignKey.DeclaringEntity.Name, Property.Format(principalKey.Properties), principalEntity.Name)); } var foreignKey = new ForeignKey(properties, principalKey, this, principalEntity); _foreignKeys.Add(foreignKey); foreach (var property in properties) { var currentKeys = property.ForeignKeys; if (currentKeys == null) { property.ForeignKeys = new ForeignKey[] { foreignKey }; } else { var newKeys = currentKeys.ToList(); newKeys.Add(foreignKey); property.ForeignKeys = newKeys; } } if (principalKey.ReferencingForeignKeys == null) { principalKey.ReferencingForeignKeys = new List <ForeignKey> { foreignKey }; } else { principalKey.ReferencingForeignKeys.Add(foreignKey); } if (principalEntity.DeclaredReferencingForeignKeys == null) { principalEntity.DeclaredReferencingForeignKeys = new List <ForeignKey> { foreignKey }; } else { principalEntity.DeclaredReferencingForeignKeys.Add(foreignKey); } if (runConventions) { Model.ConventionDispatcher.OnForeignKeyAdded(foreignKey); } return(foreignKey); }