public void AppendComparison_creates_parameters_and_adds_AND_for_multiple_comparisons()
        {
            var parameters = new EntityCommand().Parameters;

            var filterBuilder =
                EntityStoreSchemaQueryGenerator.AppendComparison(
                    new StringBuilder(),
                    "alias1",
                    "propertyName1",
                    "Value1",
                    parameters);

            EntityStoreSchemaQueryGenerator.AppendComparison(
                filterBuilder,
                "alias2",
                "propertyName2",
                "Value2",
                parameters);

            Assert.Equal(
                "alias1.propertyName1 LIKE @p0 AND alias2.propertyName2 LIKE @p1",
                filterBuilder.ToString());

            Assert.Equal(2, parameters.Count);
            Assert.Equal("p0,p1", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.ParameterName)));
            Assert.Equal("Value1,Value2", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.Value)));
        }
        /// <summary>
        ///     The constructor for the data reader, each EntityDataReader must always be associated with a EntityCommand and an underlying
        ///     DbDataReader.  It is expected that EntityDataReader only has a reference to EntityCommand and doesn't assume responsibility
        ///     of cleaning the command object, but it does assume responsibility of cleaning up the store data reader object.
        /// </summary>
        internal EntityDataReader(EntityCommand command, DbDataReader storeDataReader, CommandBehavior behavior)
        {
            Debug.Assert(command != null && storeDataReader != null);

            _command = command;
            _storeDataReader = storeDataReader;
            _storeExtendedDataRecord = storeDataReader as IExtendedDataRecord;
            _behavior = behavior;
        }
        /// <summary>
        ///     The constructor for the data reader, each EntityDataReader must always be associated with a EntityCommand and an underlying
        ///     DbDataReader.  It is expected that EntityDataReader only has a reference to EntityCommand and doesn't assume responsibility
        ///     of cleaning the command object, but it does assume responsibility of cleaning up the store data reader object.
        /// </summary>
        internal EntityDataReader(EntityCommand command, DbDataReader storeDataReader, CommandBehavior behavior)
        {
            DebugCheck.NotNull(command);
            DebugCheck.NotNull(storeDataReader);

            _command = command;
            _storeDataReader = storeDataReader;
            _storeExtendedDataRecord = storeDataReader as IExtendedDataRecord;
            _behavior = behavior;
        }
        public FunctionDetailsReader(EntityCommand command, Version storeSchemaModelVersion)
        {
            Debug.Assert(command != null, "command != null");
            Debug.Assert(storeSchemaModelVersion != null, "storeSchemaModelVersion != null");

            _rowViewFactoryMethod =
                storeSchemaModelVersion < EntityFrameworkVersion.Version3
                    ? (values) => new FunctionDetailsV1RowView(values)
                    : (Func<object[], FunctionDetailsRowView>)((values) => new FunctionDetailsV3RowView(values));

            _command = command;
            _reader = _command.ExecuteReader(CommandBehavior.SequentialAccess);
        }
        public void AppendFilterEntry_creates_filter_for_catalog_schema_and_name_if_all_specified()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "(alias.CatalogName LIKE @p0 AND alias.SchemaName LIKE @p1 AND alias.Name LIKE @p2)",
                EntityStoreSchemaQueryGenerator.AppendFilterEntry(
                    new StringBuilder(),
                    "alias",
                    new EntityStoreSchemaFilterEntry("catalog", "schema", "name"),
                    parameters).ToString());

            Assert.Equal(3, parameters.Count);
        }
        public void AppendComparison_creates_comparison_fragment_and_corresponding_parameter_for_non_null_value()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "alias.propertyName LIKE @p0",
                EntityStoreSchemaQueryGenerator.AppendComparison(
                    new StringBuilder(),
                    "alias",
                    "propertyName",
                    "Value",
                    parameters).ToString());

            Assert.Equal(1, parameters.Count);
            Assert.Equal("p0", parameters[0].ParameterName);
            Assert.Equal("Value", parameters[0].Value);
        }
        /// <summary>
        /// Creates a new instance of EntityClientCacheKey given a entityCommand instance
        /// </summary>
        /// <param name="entityCommand"></param>
        internal EntityClientCacheKey(EntityCommand entityCommand)
        {
            // Command Type
            _commandType = entityCommand.CommandType;

            // Statement
            _eSqlStatement = entityCommand.CommandText;

            // Parameters
            _parametersToken = GetParametersToken(entityCommand);
            _parameterCount = entityCommand.Parameters.Count;

            // Hashcode
            _hashCode = _commandType.GetHashCode() ^
                        _eSqlStatement.GetHashCode() ^
                        _parametersToken.GetHashCode();
        }
Exemple #8
0
        /// <summary>
        ///     Given an entity command, store provider command and a connection, sets all output parameter values on the entity command.
        ///     The connection is used to determine how to map spatial values.
        /// </summary>
        /// <param name="entityCommand"> Entity command on which to set parameter values. Must not be null. </param>
        /// <param name="storeProviderCommand"> Store provider command from which to retrieve parameter values. Must not be null. </param>
        /// <param name="connection"> The connection on which the command was run. Must not be null </param>
        internal static void SetEntityParameterValues(
            EntityCommand entityCommand, DbCommand storeProviderCommand, EntityConnection connection)
        {
            DebugCheck.NotNull(entityCommand);
            DebugCheck.NotNull(storeProviderCommand);
            DebugCheck.NotNull(connection);

            foreach (DbParameter storeParameter in storeProviderCommand.Parameters)
            {
                var direction = storeParameter.Direction;
                if (0 != (direction & ParameterDirection.Output))
                {
                    // if the entity command also defines the parameter, propagate store parameter value
                    // to entity parameter
                    var parameterOrdinal = entityCommand.Parameters.IndexOf(storeParameter.ParameterName);
                    if (0 <= parameterOrdinal)
                    {
                        var entityParameter = entityCommand.Parameters[parameterOrdinal];
                        var parameterValue = storeParameter.Value;
                        var parameterType = entityParameter.GetTypeUsage();
                        if (Helper.IsSpatialType(parameterType))
                        {
                            parameterValue = GetSpatialValueFromProviderValue(
                                parameterValue, (PrimitiveType)parameterType.EdmType, connection);
                        }
                        entityParameter.Value = parameterValue;
                    }
                }
            }
        }
 internal virtual EntityDataReader CreateEntityDataReader(
     EntityCommand entityCommand, DbDataReader storeDataReader, CommandBehavior behavior)
 {
     return new EntityDataReader(entityCommand, storeDataReader, behavior);
 }
 internal virtual void InvokeOnDataReaderClosingEvent(EntityCommand sender, EventArgs e)
 {
     OnDataReaderClosing(sender, e);
 }
        public void AppendFilterEntry_uses_OR_to_connect_multiple_filters()
        {
            var parameters = new EntityCommand().Parameters;
            var filterBuilder = new StringBuilder();

            EntityStoreSchemaQueryGenerator.AppendFilterEntry(
                filterBuilder,
                "alias",
                new EntityStoreSchemaFilterEntry(null, null, null),
                parameters);

            EntityStoreSchemaQueryGenerator.AppendFilterEntry(
                filterBuilder,
                "alias",
                new EntityStoreSchemaFilterEntry("catalog", "schema", null),
                parameters);

            Assert.Equal(
                "(alias.Name LIKE @p0) OR (alias.CatalogName LIKE @p1 AND alias.SchemaName LIKE @p2)",
                filterBuilder.ToString());

            Assert.Equal(3, parameters.Count);
            Assert.Equal("p0,p1,p2", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.ParameterName)));
            Assert.Equal("%,catalog,schema", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.Value)));
        }
        /// <summary>
        /// Returns a string representation of the parameter list
        /// </summary>
        /// <param name="entityCommand"></param>
        /// <returns></returns>
        private static string GetParametersToken(EntityCommand entityCommand)
        {
            if (null == entityCommand.Parameters
                || 0 == entityCommand.Parameters.Count)
            {
                //
                // means no parameters
                //
                return "@@0";
            }

            // Ensure that parameter DbTypes are valid and there are no duplicate names
            var paramTypeUsage = entityCommand.GetParameterTypeUsage();
            Debug.Assert(
                paramTypeUsage.Count == entityCommand.Parameters.Count,
                "entityParameter collection and query parameter collection must have the same number of entries");
            if (1 == paramTypeUsage.Count)
            {
                // if its one parameter only, there is no need to use stringbuilder
                return "@@1:" +
                       entityCommand.Parameters[0].ParameterName + ":" +
                       GetTypeUsageToken(paramTypeUsage[entityCommand.Parameters[0].ParameterName]);
            }
            else
            {
                var sb = new StringBuilder(entityCommand.Parameters.Count * EstimatedParameterStringSize);
                Debug.Assert(
                    paramTypeUsage.Count == entityCommand.Parameters.Count,
                    "entityParameter collection and query parameter collection must have the same number of entries");
                sb.Append("@@");
                sb.Append(entityCommand.Parameters.Count);
                sb.Append(":");
                var separator = "";
                foreach (var param in paramTypeUsage)
                {
                    sb.Append(separator);
                    sb.Append(param.Key);
                    sb.Append(":");
                    sb.Append(GetTypeUsageToken(param.Value));
                    separator = ";";
                }
                return sb.ToString();
            }
        }
        public void GenerateQuery_filters_out_inapplicable_filters()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "baseQuery",
                new EntityStoreSchemaQueryGenerator(
                    "baseQuery",
                    string.Empty,
                    EntityStoreSchemaFilterObjectTypes.Table,
                    new[]
                        {
                            new EntityStoreSchemaFilterEntry(
                                null,
                                null,
                                "name",
                                EntityStoreSchemaFilterObjectTypes.Function,
                                EntityStoreSchemaFilterEffect.Exclude),
                        },
                    new string[0])
                    .GenerateQuery(parameters));

            Assert.Equal(0, parameters.Count);
        }
        public void GenerateQuery_returns_base_query_if_no_orderby_clause_and_no_applicable_filters()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "baseQuery",
                new EntityStoreSchemaQueryGenerator(
                    "baseQuery",
                    string.Empty,
                    EntityStoreSchemaFilterObjectTypes.Table,
                    new EntityStoreSchemaFilterEntry[0],
                    new string[0])
                    .GenerateQuery(parameters));

            Assert.Equal(0, parameters.Count);
        }
        public void Where_clause_created_when_Allow_and_Exclude_present()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "NOT ((alias.Name LIKE @p0) OR (alias.Name LIKE @p1))",
                new EntityStoreSchemaQueryGenerator(
                    string.Empty,
                    string.Empty,
                    EntityStoreSchemaFilterObjectTypes.Table,
                    new[]
                        {
                            new EntityStoreSchemaFilterEntry(
                                null,
                                null,
                                "nameAllowed",
                                EntityStoreSchemaFilterObjectTypes.Table,
                                EntityStoreSchemaFilterEffect.Exclude),
                            new EntityStoreSchemaFilterEntry(
                                null,
                                null,
                                "nameExcluded",
                                EntityStoreSchemaFilterObjectTypes.Table,
                                EntityStoreSchemaFilterEffect.Exclude)
                        },
                    new[] { "alias" })
                    .CreateWhereClause(parameters).ToString());

            Assert.Equal(2, parameters.Count);
            Assert.Equal("p0,p1", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.ParameterName)));
            Assert.Equal("nameAllowed,nameExcluded", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.Value)));
        }
        public void Where_clause_uses_AND_to_connect_multiple_aliases_and_Exclude_filter()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "NOT ((alias1.Name LIKE @p0))\r\nAND\r\nNOT ((alias2.Name LIKE @p1))",
                new EntityStoreSchemaQueryGenerator(
                    string.Empty,
                    string.Empty,
                    EntityStoreSchemaFilterObjectTypes.Table,
                    new[]
                        {
                            new EntityStoreSchemaFilterEntry(
                                null,
                                null,
                                "name",
                                EntityStoreSchemaFilterObjectTypes.Table,
                                EntityStoreSchemaFilterEffect.Exclude),
                        },
                    new[] { "alias1", "alias2" })
                    .CreateWhereClause(parameters).ToString());

            Assert.Equal(2, parameters.Count);
            Assert.Equal("p0,p1", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.ParameterName)));
            Assert.Equal("name,name", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.Value)));
        }
        public void Where_clause_created_for_single_Exclude_filter()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "NOT ((alias.CatalogName LIKE @p0 AND alias.SchemaName LIKE @p1 AND alias.Name LIKE @p2))",
                new EntityStoreSchemaQueryGenerator(
                    string.Empty,
                    string.Empty,
                    EntityStoreSchemaFilterObjectTypes.Table,
                    new[]
                        {
                            new EntityStoreSchemaFilterEntry(
                                "catalog",
                                "schema",
                                "name",
                                EntityStoreSchemaFilterObjectTypes.Table,
                                EntityStoreSchemaFilterEffect.Exclude)
                        },
                    new[] { "alias" })
                    .CreateWhereClause(parameters).ToString());

            Assert.Equal(3, parameters.Count);
            Assert.Equal("p0,p1,p2", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.ParameterName)));
            Assert.Equal("catalog,schema,name", string.Join(",", parameters.OfType<EntityParameter>().Select(p => p.Value)));
        }
Exemple #18
0
        /// <summary>
        ///     Given an entity command and entity transaction, passes through relevant state to store provider
        ///     command.
        /// </summary>
        /// <param name="entityCommand"> Entity command. Must not be null. </param>
        /// <param name="entityTransaction"> Entity transaction. Must not be null. </param>
        /// <param name="storeProviderCommand"> Store provider command that is being setup. Must not be null. </param>
        internal static void SetStoreProviderCommandState(
            EntityCommand entityCommand, EntityTransaction entityTransaction, DbCommand storeProviderCommand)
        {
            DebugCheck.NotNull(entityCommand);
            DebugCheck.NotNull(storeProviderCommand);

            storeProviderCommand.CommandTimeout = entityCommand.CommandTimeout;
            storeProviderCommand.Connection = (entityCommand.Connection).StoreConnection;
            storeProviderCommand.Transaction = (null != entityTransaction) ? entityTransaction.StoreTransaction : null;
            storeProviderCommand.UpdatedRowSource = entityCommand.UpdatedRowSource;
        }
        private static ICollection<EntityStoreSchemaFilterEntry> ExecuteDatabaseMetadataQuery(
            string esqlQuery, EntityStoreSchemaFilterObjectTypes types, ModelBuilderSettings settings, DoWorkEventArgs args)
        {
            var filterEntries = new List<EntityStoreSchemaFilterEntry>();

            EntityConnection ec = null;
            try
            {
                Version actualEntityFrameworkConnectionVersion;
                ec = new StoreSchemaConnectionFactory().Create(
                    DependencyResolver.Instance,
                    settings.RuntimeProviderInvariantName,
                    settings.DesignTimeConnectionString,
                    settings.TargetSchemaVersion,
                    out actualEntityFrameworkConnectionVersion);

                // if the provider does not support V3 and we are querying for Functions then switch to the pre-V3 query
                if (actualEntityFrameworkConnectionVersion < EntityFrameworkVersion.Version3
                    && SelectFunctionsESqlQuery.Equals(esqlQuery, StringComparison.Ordinal))
                {
                    esqlQuery = SelectFunctionsESqlQueryBeforeV3;
                }

                using (var command = new EntityCommand(null, ec, DependencyResolver.Instance))
                {
                    // NOTE:  DO NOT set the the command.CommandTimeout value.  Some providers don't support a non-zero value, and will throw (eg, SqlCE provider). 
                    // The System.Data.SqlClient's default value is 15, so we will still get a timeout for sql server. 

                    command.CommandType = CommandType.Text;
                    command.CommandText = esqlQuery;
                    ec.Open();
                    DbDataReader reader = null;
                    try
                    {
                        reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
                        while (reader.Read())
                        {
                            if (args != null
                                && args.Cancel)
                            {
                                break;
                            }

                            if (reader.FieldCount == 3)
                            {
                                // the types coming back through the reader may not be a string 
                                // (eg, SqlCE returns System.DbNull for catalogName & schemaName), so cast carefully
                                var catalogName = reader.GetValue(0) as String;
                                var schemaName = reader.GetValue(1) as String;
                                var name = reader.GetValue(2) as String;

                                if (String.IsNullOrEmpty(name) == false)
                                {
                                    filterEntries.Add(
                                        new EntityStoreSchemaFilterEntry(
                                            catalogName, schemaName, name, types, EntityStoreSchemaFilterEffect.Allow));
                                }
                            }
                            else
                            {
                                Debug.Fail("Unexpected field count in reader");
                            }
                        }
                    }
                    finally
                    {
                        if (reader != null)
                        {
                            try
                            {
                                reader.Close();
                                reader.Dispose();
                            }
                            catch (Exception)
                            {
                                Debug.Fail(
                                    "Could not close the DbDataReader in ExecuteDatabaseMetadataQuery(). If this is the result of a connection to a database file, it will leave a read lock on the file.");
                            }
                        }
                    }
                }
            }
            finally
            {
                if (ec != null)
                {
                    try
                    {
                        ec.Close();
                        ec.Dispose();
                    }
                    catch (Exception)
                    {
                        Debug.Fail(
                            "Could not close the EntityConnection in ExecuteDatabaseMetadataQuery(). If this is a connection to a database file, it will leave a read lock on the file.");
                    }
                }
            }

            return filterEntries;
        }
        public void GenerateQuery_appends_orderby_if_specified()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "baseQuery\r\norderBy",
                new EntityStoreSchemaQueryGenerator(
                    "baseQuery",
                    "orderBy",
                    EntityStoreSchemaFilterObjectTypes.Table,
                    new EntityStoreSchemaFilterEntry[0],
                    new string[0])
                    .GenerateQuery(parameters));

            Assert.Equal(0, parameters.Count);
        }
    public void UserDefinedFunction()
    {
      using (EntityConnection conn = new EntityConnection("name=testEntities"))
      {
        conn.Open();

        string query = @"SELECT e.FirstName AS Name FROM testEntities.Employees AS e 
                    WHERE testModel.Store.spFunc(e.Id, '') = 6";
        using (EntityCommand cmd = new EntityCommand(query, conn))
        {
          EntityDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
          Assert.IsTrue(reader.Read());
          Assert.AreEqual("Scooby", reader[0]);
        }
      }
    }
        /// <summary>
        ///     Closes the <see cref="T:System.Data.Entity.Core.EntityClient.EntityDataReader" /> object.
        /// </summary>
        public override void Close()
        {
            if (_command != null)
            {
                _storeDataReader.Close();

                // Notify the command object that we are closing, so clean up operations such as copying output parameters can be done
                _command.NotifyDataReaderClosing();
                if ((_behavior & CommandBehavior.CloseConnection)
                    == CommandBehavior.CloseConnection)
                {
                    Debug.Assert(_command.Connection != null);
                    _command.Connection.Close();
                }

                _command = null;
            }
        }
 public EntityStoreSchemaGeneratorDatabaseSchemaLoaderFake(EntityCommand[] entityCommands)
     : base(new Mock<EntityConnection>().Object, EntityFrameworkVersion.Version3)
 {
     _entityCommands = entityCommands;
 }
        public void AppendFilterEntry_uses_wildcard_parameter_value_if_schema_catalog_and_name_are_null()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "(alias.Name LIKE @p0)",
                EntityStoreSchemaQueryGenerator.AppendFilterEntry(
                    new StringBuilder(),
                    "alias",
                    new EntityStoreSchemaFilterEntry(null, null, null),
                    parameters).ToString());

            Assert.Equal(1, parameters.Count);
            Assert.Equal("p0", parameters[0].ParameterName);
            Assert.Equal("%", parameters[0].Value);
        }
        public void GenerateQuery_appends_orderby_after_where_clause_if_both_are_present()
        {
            var parameters = new EntityCommand().Parameters;

            Assert.Equal(
                "baseQuery\r\nWHERE\r\nNOT ((alias.Name LIKE @p0))\r\norderby",
                new EntityStoreSchemaQueryGenerator(
                    "baseQuery",
                    "orderby",
                    EntityStoreSchemaFilterObjectTypes.Function,
                    new[]
                        {
                            new EntityStoreSchemaFilterEntry(
                                null,
                                null,
                                "name",
                                EntityStoreSchemaFilterObjectTypes.Function,
                                EntityStoreSchemaFilterEffect.Exclude),
                        },
                    new[] { "alias" })
                    .GenerateQuery(parameters));

            Assert.Equal(1, parameters.Count);
            Assert.Equal("p0", parameters[0].ParameterName);
            Assert.Equal("name", parameters[0].Value);
        }
 public EntityStoreSchemaGeneratorDatabaseSchemaLoaderFake(EntityCommand entityCommand)
     : this(new[] { entityCommand })
 {
 }