/// <summary>
        /// Initializes a new instance of the <see cref="UnitOfWork" /> class.
        /// </summary>
        /// <param name="context">The database context.</param>
        /// <param name="databaseProvider">
        /// The database provider that inherited from
        /// <see cref="System.Data.Entity.Core.Common.DbProviderServices" /> abstract class.
        /// </param>
        /// <param name="dbCommandInterceptor">The database command interceptor for logging.</param>
        /// <param name="lazyLoad">if set to <c>true</c> EF will not load related entities, you should manual load that by eager loading.
        /// by default EF set this flag is <c>false</c>.</param>
        /// <exception cref="System.ArgumentNullException">When context parameter is null.</exception>
        /// <exception cref="System.ArgumentException">When database does not exist. This exception will occur when set checkDbExists to true.</exception>
        public UnitOfWork(TDbContext context, System.Data.Entity.Core.Common.DbProviderServices databaseProvider,
                          IDbCommandInterceptor dbCommandInterceptor = null, bool lazyLoad = true)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // Disables auto-generate database.
            Database.SetInitializer <TDbContext>(null);

            _context = context;
            // Sets to false for high performance but has to use with ChangeTracker.DetectChanges method to detect later when you want.
            _context.Configuration.AutoDetectChangesEnabled = false;
            // Sets to false for high performance but has to use with eager loading for all navigation properties
            // you want to use (Include on ObjectQuery), by default EF will set to false and no need to use eager loading
            // EF will automatic lading all related entities at first times.
            // <a href="https://msdn.microsoft.com/en-us/data/hh949853.aspx" target="_blank"> For more information.</a>
            _context.Configuration.LazyLoadingEnabled = lazyLoad;

            // Adds interceptor for logging all sql scripts.
            if (dbCommandInterceptor != null)
            {
                DbInterception.Add(dbCommandInterceptor);
            }

            // Initializes container.
            _repositoriesContainer = new Dictionary <string, dynamic>();
        }
Пример #2
0
 public void Dispose()
 {
     if (_commandInterceptor != null)
     {
         _commandInterceptor.IsEnabled = false;
         _commandInterceptor           = null;
     }
 }
Пример #3
0
 public void Dispose()
 {
     if (_commandInterceptor != null)
     {
         _commandInterceptor.IsEnabled = false;
         _commandInterceptor = null;
     }
 }
Пример #4
0
        /// <summary>
        ///     Creates a new instance with all options the same as for this instance, but with the given option changed.
        ///     It is unusual to call this method directly. Instead use <see cref="DbContextOptionsBuilder" />.
        /// </summary>
        /// <param name="commandInterceptor"> The option to change. </param>
        /// <returns> A new instance with the option changed. </returns>
        public virtual RelationalOptionsExtension WithCommandInterceptor(
            [CanBeNull] IDbCommandInterceptor commandInterceptor)
        {
            var clone = Clone();

            clone._commandInterceptor = commandInterceptor;

            return(clone);
        }
Пример #5
0
        public CommandTracer(IDbCommandInterceptor commandInterceptor = null)
        {
            _commandInterceptor
                = commandInterceptor
                  ?? DbConfiguration.GetService<IDbCommandInterceptor>();

            if (_commandInterceptor != null)
            {
                _commandInterceptor.IsEnabled = true;
            }
        }
Пример #6
0
        public CommandTracer(IDbCommandInterceptor commandInterceptor = null)
        {
            _commandInterceptor
                = commandInterceptor
                  ?? DbConfiguration.GetService <IDbCommandInterceptor>();

            if (_commandInterceptor != null)
            {
                _commandInterceptor.IsEnabled = true;
            }
        }
Пример #7
0
        /// <summary>
        ///     We resolve this lazily because loggers are created very early in the initialization
        ///     process where <see cref="IDbContextOptions"/> is not yet available from D.I.
        ///     This means those loggers can't do interception, but that's okay because nothing
        ///     else is ready for them to do interception anyway.
        /// </summary>
        private bool TryFindAppInterceptor(out IDbCommandInterceptor interceptor)
        {
            interceptor = Dependencies
                          .ServiceProvider
                          .GetService <IDbContextOptions>()
                          .Extensions
                          .OfType <RelationalOptionsExtension>()
                          .FirstOrDefault()
                          ?.CommandInterceptor;

            return(interceptor != null);
        }
Пример #8
0
        public static void Add(IDbCommandInterceptor interceptor)
        {
            PublicHelper.CheckNull(interceptor);

            lock (_lockObject)
            {
                List <IDbCommandInterceptor> newList = _interceptors.ToList();
                newList.Add(interceptor);
                newList.TrimExcess();
                _interceptors = newList;
            }
        }
Пример #9
0
        public static void Remove(IDbCommandInterceptor interceptor)
        {
            Checks.NotNull(interceptor, "interceptor");

            lock (_lockObject)
            {
                List <IDbCommandInterceptor> newList = _interceptors.ToList();
                newList.Remove(interceptor);
                newList.TrimExcess();
                _interceptors = newList;
            }
        }
Пример #10
0
        /// <summary>
        ///     Called by a derived class constructor when implementing the <see cref="Clone" /> method.
        /// </summary>
        /// <param name="copyFrom"> The instance that is being cloned. </param>
        protected RelationalOptionsExtension([NotNull] RelationalOptionsExtension copyFrom)
        {
            Check.NotNull(copyFrom, nameof(copyFrom));

            _connectionString             = copyFrom._connectionString;
            _connection                   = copyFrom._connection;
            _commandTimeout               = copyFrom._commandTimeout;
            _maxBatchSize                 = copyFrom._maxBatchSize;
            _minBatchSize                 = copyFrom._minBatchSize;
            _useRelationalNulls           = copyFrom._useRelationalNulls;
            _migrationsAssembly           = copyFrom._migrationsAssembly;
            _migrationsHistoryTableName   = copyFrom._migrationsHistoryTableName;
            _migrationsHistoryTableSchema = copyFrom._migrationsHistoryTableSchema;
            _executionStrategyFactory     = copyFrom._executionStrategyFactory;
            _commandInterceptor           = copyFrom._commandInterceptor;
        }
        public EntityStoreSchemaGeneratorDatabaseSchemaLoader(
            EntityConnection entityConnection,
            Version storeSchemaModelVersion)
        {
            Debug.Assert(entityConnection != null, "entityConnection != null");
            Debug.Assert(entityConnection.State == ConnectionState.Closed, "expected closed connection");
            Debug.Assert(EntityFrameworkVersion.IsValidVersion(storeSchemaModelVersion), "invalid version");

            _connection = entityConnection;
            _storeSchemaModelVersion = storeSchemaModelVersion;

            if (_connection != null &&
                _connection.StoreConnection != null &&
                string.Equals(
                    _connection.StoreConnection.GetProviderInvariantName(),
                    SqlServerInvariantName,
                    StringComparison.Ordinal) &&
                !SwitchOffMetadataMergeJoins())
            {
                _addOptionMergeJoinInterceptor = new AddOptionMergeJoinInterceptor();
            }
        }
Пример #12
0
        public EntityStoreSchemaGeneratorDatabaseSchemaLoader(
            EntityConnection entityConnection,
            Version storeSchemaModelVersion)
        {
            Debug.Assert(entityConnection != null, "entityConnection != null");
            Debug.Assert(entityConnection.State == ConnectionState.Closed, "expected closed connection");
            Debug.Assert(EntityFrameworkVersion.IsValidVersion(storeSchemaModelVersion), "invalid version");

            _connection = entityConnection;
            _storeSchemaModelVersion = storeSchemaModelVersion;

            var isSqlServer = false;

            try
            {
                if (_connection != null &&
                    _connection.StoreConnection != null &&
                    string.Equals(
                        _connection.StoreConnection.GetProviderInvariantName(),
                        SqlServerInvariantName,
                        StringComparison.Ordinal))
                {
                    isSqlServer = true;
                }
            }
            catch (Exception)
            {
                // Several exceptions can be thrown from GetProviderInvariantName().
                // Assume that the provider is not SqlServer unless we can confirm it is.
            }

            if (isSqlServer && !SwitchOffMetadataMergeJoins())
            {
                _addOptionMergeJoinInterceptor = new AddOptionMergeJoinInterceptor();
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="TraceableSqlCommand"/> class.
 /// </summary>
 /// <param name="collectSqlQueries">
 /// Include the <see cref="TraceableSqlCommand.CommandText" /> in the sanitized_query section of
 /// the SQL subsegment. Parameterized values will appear in their tokenized form and will not be expanded.
 /// You should not enable this flag if you are including sensitive information as clear text.
 /// This flag will override any behavior configured by <see cref="XRayOptions.CollectSqlQueries" />.
 /// If a value is not provided, then the globally configured value will be used, which is false by default.
 /// See the official documentation on <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=netframework-4.7.2">SqlCommand.Parameters</a>
 /// </param>
 public TraceableSqlCommand(bool?collectSqlQueries = null)
 {
     InnerSqlCommand = new SqlCommand();
     _interceptor    = new DbCommandInterceptor(AWSXRayRecorder.Instance, collectSqlQueries);
 }
 /// <summary>
 /// Initializes the interceptor
 /// </summary>
 public ProfilingInterceptor() {
     this._internalInstance = DependencyFactory.GetService<IDbCommandInterceptor>();
 }
 /// <summary>
 ///     <para>
 ///         Configures the context to use the given <see cref="IDbCommandInterceptor" />.
 ///     </para>
 ///     <para>
 ///         Note that only a single <see cref="IDbCommandInterceptor" /> can be registered.
 ///         Use <see cref="CompositeDbCommandInterceptor"/> to combine multiple interceptors into one.
 ///     </para>
 /// </summary>
 /// <param name="interceptor"> The interceptor to use. </param>
 public virtual TBuilder CommandInterceptor(
     [NotNull] IDbCommandInterceptor interceptor)
 => WithOption(e => (TExtension)e.WithCommandInterceptor(Check.NotNull(interceptor, nameof(interceptor))));
Пример #16
0
        /// <summary>
        ///     See comments in <see cref="UpdateCommand" />.
        /// </summary>
        internal override long Execute(
            Dictionary <int, object> identifierValues,
            List <KeyValuePair <PropagatorResult, object> > generatedValues,
            IDbCommandInterceptor commandInterceptor)
        {
            // Compile command
            using (var command = CreateCommand(identifierValues))
            {
                var connection = Translator.Connection;
                // configure command to use the connection and transaction for this session
                command.Transaction = ((null == connection.CurrentTransaction)
                                           ? null
                                           : connection.CurrentTransaction.StoreTransaction);
                command.Connection = connection.StoreConnection;
                if (Translator.CommandTimeout.HasValue)
                {
                    command.CommandTimeout = Translator.CommandTimeout.Value;
                }

                // Execute the query
                int rowsAffected;
                if (_modificationCommandTree.HasReader)
                {
                    // retrieve server gen results
                    rowsAffected = 0;
                    using (var reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
                    {
                        if (reader.Read())
                        {
                            rowsAffected++;

                            var members = TypeHelpers.GetAllStructuralMembers(CurrentValues.StructuralType);

                            for (var ordinal = 0; ordinal < reader.FieldCount; ordinal++)
                            {
                                // column name of result corresponds to column name of table
                                var    columnName = reader.GetName(ordinal);
                                var    member     = members[columnName];
                                object value;
                                if (Helper.IsSpatialType(member.TypeUsage) &&
                                    !reader.IsDBNull(ordinal))
                                {
                                    value = SpatialHelpers.GetSpatialValue(Translator.MetadataWorkspace, reader, member.TypeUsage, ordinal);
                                }
                                else
                                {
                                    value = reader.GetValue(ordinal);
                                }

                                // retrieve result which includes the context for back-propagation
                                var columnOrdinal = members.IndexOf(member);
                                var result        = CurrentValues.GetMemberValue(columnOrdinal);

                                // register for back-propagation
                                generatedValues.Add(new KeyValuePair <PropagatorResult, object>(result, value));

                                // register identifier if it exists
                                var identifier = result.Identifier;
                                if (PropagatorResult.NullIdentifier != identifier)
                                {
                                    identifierValues.Add(identifier, value);
                                }
                            }
                        }

                        // Consume the current reader (and subsequent result sets) so that any errors
                        // executing the command can be intercepted
                        CommandHelper.ConsumeReader(reader);
                    }
                }
                else
                {
                    // We currently only intercept commands on this code path.

                    var executeCommand = true;

                    if (commandInterceptor != null)
                    {
                        executeCommand = commandInterceptor.Intercept(command);
                    }

                    rowsAffected = executeCommand ? command.ExecuteNonQuery() : 1;
                }

                return(rowsAffected);
            }
        }
Пример #17
0
 public WithInterception(IDbCommandInterceptor interceptor)
 {
     this.interceptor = interceptor;
     DbInterception.Add(this.interceptor);
 }
Пример #18
0
 protected abstract void RemoveInterceptor(IDbCommandInterceptor interceptor);
Пример #19
0
 public void RemoveInterceptor(IDbCommandInterceptor interceptor)
 {
     PublicHelper.CheckNull(interceptor, "interceptor");
     this._dbContext.AdoSession.SessionInterceptors.Remove(interceptor);
 }
Пример #20
0
 /// <summary>
 /// 移除拦截器
 /// </summary>
 public static void Remove(IDbCommandInterceptor interceptor)
 {
     _interceptors.Remove(interceptor);
 }
Пример #21
0
 public void RemoveInterceptor(IDbCommandInterceptor interceptor)
 {
     Utils.CheckNull(interceptor, "interceptor");
     this._dbContext.AdoSession.DbCommandInterceptors.Remove(interceptor);
 }
Пример #22
0
 public void AddInterceptor(IDbCommandInterceptor interceptor)
 {
     Utils.CheckNull(interceptor, "interceptor");
     this._dbContext.InnerDbSession.DbCommandInterceptors.Add(interceptor);
 }
Пример #23
0
        /// <summary>
        ///     See comments in <see cref="UpdateCommand" />.
        /// </summary>
        internal override long Execute(
            Dictionary <int, object> identifierValues,
            List <KeyValuePair <PropagatorResult, object> > generatedValues,
            IDbCommandInterceptor commandInterceptor)
        {
            var connection = Translator.Connection;

            // configure command to use the connection and transaction for this session
            _dbCommand.Transaction = ((null == connection.CurrentTransaction)
                                          ? null
                                          : connection.CurrentTransaction.StoreTransaction);
            _dbCommand.Connection = connection.StoreConnection;
            if (Translator.CommandTimeout.HasValue)
            {
                _dbCommand.CommandTimeout = Translator.CommandTimeout.Value;
            }

            SetInputIdentifiers(identifierValues);

            // Execute the query
            long rowsAffected;

            if (null != ResultColumns)
            {
                // If there are result columns, read the server gen results
                rowsAffected = 0;
                var members = TypeHelpers.GetAllStructuralMembers(CurrentValues.StructuralType);
                using (var reader = _dbCommand.ExecuteReader(CommandBehavior.SequentialAccess))
                {
                    // Retrieve only the first row from the first result set
                    if (reader.Read())
                    {
                        rowsAffected++;

                        foreach (var resultColumn in ResultColumns
                                 .Select(r => new KeyValuePair <int, PropagatorResult>(GetColumnOrdinal(Translator, reader, r.Key), r.Value))
                                 .OrderBy(r => r.Key)) // order by column ordinal to avoid breaking SequentialAccess readers
                        {
                            var    columnOrdinal = resultColumn.Key;
                            var    columnType    = members[resultColumn.Value.RecordOrdinal].TypeUsage;
                            object value;

                            if (Helper.IsSpatialType(columnType) &&
                                !reader.IsDBNull(columnOrdinal))
                            {
                                value = SpatialHelpers.GetSpatialValue(Translator.MetadataWorkspace, reader, columnType, columnOrdinal);
                            }
                            else
                            {
                                value = reader.GetValue(columnOrdinal);
                            }

                            // register for back-propagation
                            var result = resultColumn.Value;
                            generatedValues.Add(new KeyValuePair <PropagatorResult, object>(result, value));

                            // register identifier if it exists
                            var identifier = result.Identifier;
                            if (PropagatorResult.NullIdentifier != identifier)
                            {
                                identifierValues.Add(identifier, value);
                            }
                        }
                    }

                    // Consume the current reader (and subsequent result sets) so that any errors
                    // executing the function can be intercepted
                    CommandHelper.ConsumeReader(reader);
                }
            }
            else
            {
                rowsAffected = _dbCommand.ExecuteNonQuery();
            }

            return(GetRowsAffected(rowsAffected, Translator));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DSUnitOfWork" /> class.
 /// </summary>
 /// <param name="dbContext">The database context what inherits from DbContext of EF.</param>
 /// <param name="dbCommandInterceptor">The database command interceptor for logging.</param>
 public DSUnitOfWork(DbContext dbContext, IDbCommandInterceptor dbCommandInterceptor = null)
     : base(dbContext, SqlProviderServices.Instance, dbCommandInterceptor)
 {
 }
Пример #25
0
 /// <summary>
 ///     Executes the current update command.
 ///     All server-generated values are added to the generatedValues list. If those values are identifiers, they are
 ///     also added to the identifierValues dictionary, which associates proxy identifiers for keys in the session
 ///     with their actual values, permitting fix-up of identifiers across relationships.
 /// </summary>
 /// <param name="identifierValues"> Aggregator for identifier values (read for InputIdentifiers; write for OutputIdentifiers </param>
 /// <param name="generatedValues"> Aggregator for server generated values. </param>
 /// <returns> Number of rows affected by the command. </returns>
 internal abstract long Execute(
     Dictionary <int, object> identifierValues,
     List <KeyValuePair <PropagatorResult, object> > generatedValues,
     IDbCommandInterceptor commandInterceptor);
Пример #26
0
 /// <summary>
 /// 注册拦截器
 /// </summary>
 public static void Add(IDbCommandInterceptor interceptor)
 {
     _interceptors.Add(interceptor);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TraceableSqlCommand"/> class.
 /// </summary>
 /// <param name="cmdText">The text of the query.</param>
 /// <param name="connection">The connection to an instance of SQL Server.</param>
 /// <param name="collectSqlQueries">
 /// Include the <see cref="TraceableSqlCommand.CommandText" /> in the sanitized_query section of
 /// the SQL subsegment. Parameterized values will appear in their tokenized form and will not be expanded.
 /// You should not enable this flag if you are including sensitive information as clear text.
 /// This flag will override any behavior configured by <see cref="XRayOptions.CollectSqlQueries" />.
 /// If a value is not provided, then the globally configured value will be used, which is false by default.
 /// See the official documentation on <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=netframework-4.7.2">SqlCommand.Parameters</a>
 /// </param>
 public TraceableSqlCommand(string cmdText, SqlConnection connection, bool?collectSqlQueries = null)
 {
     InnerSqlCommand = new SqlCommand(cmdText, connection);
     _interceptor    = new DbCommandInterceptor(AWSXRayRecorder.Instance, collectSqlQueries);
 }
Пример #28
0
        public static TResult WithCommandInterceptor <TContext, TResult>(this TContext context, Func <TContext, TResult> function, IDbCommandInterceptor interceptor)
            where TContext : DbContext
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (function == null)
            {
                throw new ArgumentNullException(nameof(function));
            }
            if (interceptor == null)
            {
                throw new ArgumentNullException(nameof(interceptor));
            }
            DbInterception.Add(interceptor);
            var result = function(context);

            DbInterception.Remove(interceptor);
            return(result);
        }
Пример #29
0
 protected abstract void AddInterceptor(IDbCommandInterceptor interceptor);