/// <summary> /// Searches through all changes that caused a concurrency conflict in the DataContext and /// compiles an error message listing all the conflicts on all tables and each member (field) that caused the conflicts. /// This method should be called after having called SubmitChanges on a DataContext and where a ChangeConflictException /// has occured. /// </summary> /// <returns></returns> public static string GetLinqToSqlChangeConflictErrorMessage(DataContext dataContext) { StringBuilder result = new StringBuilder(); result.AppendLine("LINQ to SQL optimistic concurrency error:"); result.AppendLine(); foreach (ObjectChangeConflict conflict in dataContext.ChangeConflicts) { MetaTable metatable = dataContext.Mapping.GetTable(conflict.Object.GetType()); result.AppendLine($"Conflict Table name: {metatable.TableName}"); object entityInConflict = conflict.Object; PropertyInfo surrogateKey = EntityReaderWindows.GetLinqToSqlEntitySurrogateKey(entityInConflict.GetType()); bool containsIdentityColumn = EntityReaderWindows.IsLinqToSqlEntityPropertyIdentityColumn(surrogateKey); object surrogateKeyValue = surrogateKey.GetValue(entityInConflict, null); result.Append($"Conflict Entity ID: {surrogateKeyValue}"); foreach (MemberChangeConflict memberConflict in conflict.MemberConflicts) { object currentValue = memberConflict.CurrentValue; object originalValue = memberConflict.OriginalValue; object databaseValue = memberConflict.DatabaseValue; MemberInfo member = memberConflict.Member; result.AppendLine($"Conflict Member: {member.Name}"); result.AppendLine($"Current Value: {currentValue}"); result.AppendLine($"Original Value {originalValue}"); result.AppendLine($"Database Value: {databaseValue}"); } result.AppendLine(); } return(result.ToString()); }
/// <summary> /// Determines the primary key of an entity type. The first primary key found on the entity type i.e. /// the assumption is made that the entity type only has one primary key, which is the surrogate key. /// </summary> /// <typeparam name="E">The entity type i.e. the table whose surrogate key needs to be determined.</typeparam> /// <returns>Retruns the PropertyInfo corresponding to the column which is the surrogate key for the specified entity type.</returns> public virtual PropertyInfo GetEntitySurrogateKey(Type entityType) { return(EntityReaderWindows.GetLinqToSqlEntitySurrogateKey(entityType)); }
/// <summary> /// Determines the primary key of an entity type. The first primary key found on the entity type i.e. /// the assumption is made that the entity type only has one primary key, which is the surrogate key. /// </summary> /// <typeparam name="E">The entity type i.e. the table whose surrogate key needs to be determined.</typeparam> /// <returns>Retruns the PropertyInfo corresponding to the column which is the surrogate key for the specified entity type.</returns> public virtual PropertyInfo GetEntitySurrogateKey <E>() { return(EntityReaderWindows.GetLinqToSqlEntitySurrogateKey <E>()); }