Пример #1
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override void ValidateSharedKeysCompatibility(
            IReadOnlyList <IEntityType> mappedTypes, string tableName)
        {
            base.ValidateSharedKeysCompatibility(mappedTypes, tableName);

            var keyMappings = new Dictionary <string, IKey>();

            foreach (var key in mappedTypes.SelectMany(et => et.GetDeclaredKeys()))
            {
                var keyName = key.Relational().Name;

                if (!keyMappings.TryGetValue(keyName, out var duplicateKey))
                {
                    keyMappings[keyName] = key;
                    continue;
                }

                if (key.MySql().IsClustered
                    != duplicateKey.MySql().IsClustered)
                {
                    throw new InvalidOperationException(
                              MySqlStrings.DuplicateKeyMismatchedClustering(
                                  Property.Format(key.Properties),
                                  key.DeclaringEntityType.DisplayName(),
                                  Property.Format(duplicateKey.Properties),
                                  duplicateKey.DeclaringEntityType.DisplayName(),
                                  tableName,
                                  keyName));
                }
            }
        }
Пример #2
0
        public virtual void Detects_incompatible_non_clustered_shared_key(bool obsolete)
        {
            var modelBuilder = CreateConventionalModelBuilder();

            modelBuilder.Entity <A>().HasOne <B>().WithOne().IsRequired().HasForeignKey <A>(a => a.Id).HasPrincipalKey <B>(b => b.Id);

            if (obsolete)
            {
#pragma warning disable 618
                modelBuilder.Entity <A>().ToTable("Table")
                .HasKey(a => a.Id).ForMySqlIsClustered();
                modelBuilder.Entity <B>().ToTable("Table")
                .HasKey(b => b.Id).ForMySqlIsClustered(false);
#pragma warning restore 618
            }
            else
            {
                modelBuilder.Entity <A>().ToTable("Table")
                .HasKey(a => a.Id).IsClustered();
                modelBuilder.Entity <B>().ToTable("Table")
                .HasKey(b => b.Id).IsClustered(false);
            }

            VerifyError(
                MySqlStrings.DuplicateKeyMismatchedClustering("{'Id'}", nameof(B), "{'Id'}", nameof(A), "Table", "PK_Table"),
                modelBuilder.Model);
        }
Пример #3
0
 /// <summary>
 ///     Returns the distance between g1 and g2, measured in the length unit of the spatial reference system
 ///     (SRS) of the geometry arguments.
 ///     For MySQL 8, this is equivalent of calling ST_Distance() when using an SRID of `0`.
 ///     For MySQL &lt; 8 and MariaDB, this is equivalent of calling ST_Distance() with any SRID.
 /// </summary>
 /// <param name="_">The DbFunctions instance.</param>
 /// <param name="g1">First geometry argument.</param>
 /// <param name="g2">Second geometry argument.</param>
 /// <returns>Distance betweeen g1 and g2.</returns>
 public static double SpatialDistancePlanar(
     [CanBeNull] this DbFunctions _,
     Geometry g1,
     Geometry g2)
 {
     throw new InvalidOperationException(MySqlStrings.FunctionOnClient(nameof(SpatialDistancePlanar)));
 }
Пример #4
0
        public virtual void Detects_duplicate_column_names_within_hierarchy_with_different_value_generation_strategy(bool obsolete)
        {
            var modelBuilder = CreateConventionalModelBuilder();

            modelBuilder.Entity <Animal>();
            modelBuilder.Entity <Cat>(
                cb =>
            {
                if (obsolete)
                {
#pragma warning disable 618
                    cb.Property(c => c.Identity).UseMySqlIdentityColumn();
#pragma warning restore 618
                }
                else
                {
                    cb.Property(c => c.Identity).UseIdentityColumn();
                }
                cb.Property(c => c.Identity).HasColumnName(nameof(Cat.Identity));
            });
            modelBuilder.Entity <Dog>(
                db =>
            {
                db.Property(d => d.Identity).ValueGeneratedNever();
                db.Property(c => c.Identity).HasColumnName(nameof(Dog.Identity));
            });

            VerifyError(
                MySqlStrings.DuplicateColumnNameValueGenerationStrategyMismatch(
                    nameof(Cat), nameof(Cat.Identity), nameof(Dog), nameof(Dog.Identity), nameof(Cat.Identity), nameof(Animal)),
                modelBuilder.Model);
        }
Пример #5
0
 public override Task Using_static_string_Equals_with_StringComparison_throws_informative_error(bool async)
 {
     return(AssertTranslationFailedWithDetails(
                () => AssertQuery(
                    async,
                    ss => ss.Set <Customer>().Where(c => string.Equals(c.CustomerID, "ALFKI", StringComparison.InvariantCulture))),
                MySqlStrings.QueryUnableToTranslateMethodWithStringComparison(nameof(String), nameof(string.Equals), nameof(MySqlDbContextOptionsBuilder.EnableStringComparisonTranslations))));
 }
Пример #6
0
 /// <summary>
 ///     Returns the mimimum spherical distance between Point or MultiPoint arguments on a sphere in meters,
 ///     by using the specified algorithm.
 ///     It is assumed that `g1` and `g2` are associated with an SRID of `4326`.
 /// </summary>
 /// <param name="_">The DbFunctions instance.</param>
 /// <param name="g1">First geometry argument.</param>
 /// <param name="g2">Second geometry argument.</param>
 /// <param name="algorithm">The algorithm to use. Must be directly supplied as a constant.</param>
 /// <returns>Distance betweeen g1 and g2.</returns>
 public static double SpatialDistanceSphere(
     [CanBeNull] this DbFunctions _,
     Geometry g1,
     Geometry g2,
     SpatialDistanceAlgorithm algorithm)
 {
     throw new InvalidOperationException(MySqlStrings.FunctionOnClient(nameof(SpatialDistanceSphere)));
 }
        public void Throws_for_non_key_SequenceHiLo()
        {
            var modelBuilder = CreateConventionalModelBuilder();

            modelBuilder.Entity <Dog>().Property(c => c.Type).ForMySqlUseSequenceHiLo();

            VerifyError(MySqlStrings.NonKeyValueGeneration(nameof(Dog.Type), nameof(Dog)), modelBuilder.Model);
        }
        public void IsDate_should_throw_on_client_eval()
        {
            var exIsDate = Assert.Throws <InvalidOperationException>(() => EF.Functions.IsDate("#ISDATE#"));

            Assert.Equal(
                MySqlStrings.FunctionOnClient(nameof(MySqlDbFunctionsExtensions.IsDate)),
                exIsDate.Message);
        }
Пример #9
0
        public void Throws_for_naked_type_name(string typeName)
        {
            var mapper = CreateTypeMapper();

            Assert.Equal(
                MySqlStrings.UnqualifiedDataType(typeName),
                Assert.Throws <ArgumentException>(() => mapper.FindMapping(typeName)).Message);
        }
        public void Throws_for_indexed_include_properties()
        {
            var modelBuilder = InMemoryTestHelpers.Instance.CreateConventionBuilder();

            modelBuilder.Entity <Dog>().Property(c => c.Type);
            modelBuilder.Entity <Dog>().HasIndex(nameof(Dog.Name)).ForMySqlInclude(nameof(Dog.Name));

            VerifyError(MySqlStrings.IncludePropertyInIndex(nameof(Dog), nameof(Dog.Name)), modelBuilder.Model);
        }
        public void Throws_for_multiple_identity_properties()
        {
            var modelBuilder = InMemoryTestHelpers.Instance.CreateConventionBuilder();

            modelBuilder.Entity <Dog>().Property(c => c.Type).UseMySqlIdentityColumn();
            modelBuilder.Entity <Dog>().Property <int?>("Tag").UseMySqlIdentityColumn();

            VerifyError(MySqlStrings.MultipleIdentityColumns("'Dog.Tag', 'Dog.Type'", nameof(Dog)), modelBuilder.Model);
        }
        protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
        {
            if (NewArrayExpressionSupportMethodInfos.Contains(methodCallExpression.Method))
            {
                var arguments = new Expression[methodCallExpression.Arguments.Count];
                for (var i = 0; i < arguments.Length; i++)
                {
                    var argument = methodCallExpression.Arguments[i];

                    if (argument is NewArrayExpression newArrayExpression)
                    {
                        if (TranslationFailed(argument, VisitMethodCallNewArray(newArrayExpression), out var sqlExpression))
                        {
                            return(null);
                        }

                        arguments[i] = sqlExpression;
                    }
                    else
                    {
                        arguments[i] = argument;
                    }
                }

                methodCallExpression = methodCallExpression.Update(methodCallExpression.Object, arguments);
            }

            var result = base.VisitMethodCall(methodCallExpression);

            if (result == null &&
                MySqlStringComparisonMethodTranslator.StringComparisonMethodInfos.Any(m => m == methodCallExpression.Method))
            {
                var message = MySqlStrings.QueryUnableToTranslateMethodWithStringComparison(
                    methodCallExpression.Method.DeclaringType.Name,
                    methodCallExpression.Method.Name,
                    nameof(MySqlDbContextOptionsBuilder.EnableStringComparisonTranslations));

                // EF Core returns an error message on its own, when the string.Equals() methods (static and non-static) are being used with
                // a `StringComparison` parameter.
                // Since we also support other translations, but all of them only when opted in, we will replace the EF Core error message
                // with our own, that is more appropriate for our case.
                if (TranslationErrorDetails.Contains(CoreStrings.QueryUnableToTranslateStringEqualsWithStringComparison))
                {
                    var translationErrorDetails = TranslationErrorDetails;
                    ResetTranslationErrorDetails();
                    message = translationErrorDetails.Replace(CoreStrings.QueryUnableToTranslateStringEqualsWithStringComparison, message);
                }

                AddTranslationErrorDetails(message);
            }

            return(result);
        }
        public virtual void Detects_incompatible_memory_optimized_shared_table()
        {
            var modelBuilder = CreateConventionalModelBuilder();

            modelBuilder.Entity <A>().HasOne <B>().WithOne().IsRequired().HasForeignKey <A>(a => a.Id).HasPrincipalKey <B>(b => b.Id);
            modelBuilder.Entity <A>().ToTable("Table").ForMySqlIsMemoryOptimized();
            modelBuilder.Entity <B>().ToTable("Table");

            VerifyError(
                MySqlStrings.IncompatibleTableMemoryOptimizedMismatch("Table", nameof(A), nameof(B), nameof(A), nameof(B)),
                modelBuilder.Model);
        }
Пример #14
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override void ValidateMapping(CoreTypeMapping mapping, IProperty property)
        {
            var relationalMapping = mapping as RelationalTypeMapping;

            if (_disallowedMappings.Contains(relationalMapping?.StoreType))
            {
                if (property == null)
                {
                    throw new ArgumentException(MySqlStrings.UnqualifiedDataType(relationalMapping.StoreType));
                }

                throw new ArgumentException(MySqlStrings.UnqualifiedDataTypeOnProperty(relationalMapping.StoreType, property.Name));
            }
        }
        private static (string Schema, string Table) Parse(string table)
        {
            var match = _partExtractor.Match(table.Trim());

            if (!match.Success)
            {
                throw new InvalidOperationException(MySqlStrings.InvalidTableToIncludeInScaffolding(table));
            }

            var part1 = match.Groups["part1"].Value.Replace("]]", "]");
            var part2 = match.Groups["part2"].Value.Replace("]]", "]");

            return(string.IsNullOrEmpty(part2) ? (null, part1) : (part1, part2));
        }
        public void Throws_setting_identity_generation_for_invalid_type()
        {
            var modelBuilder = GetModelBuilder();

            var property = modelBuilder
                           .Entity <Customer>()
                           .Property(e => e.Name)
                           .Metadata;

            Assert.Equal(
                MySqlStrings.IdentityBadType("Name", nameof(Customer), "string"),
                Assert.Throws <ArgumentException>(
                    () => property.SetValueGenerationStrategy(MySqlValueGenerationStrategy.IdentityColumn)).Message);
        }
        public void Contains_should_throw_on_client_eval()
        {
            var exNoLang = Assert.Throws <InvalidOperationException>(() => EF.Functions.Contains("teststring", "teststring"));

            Assert.Equal(
                MySqlStrings.FunctionOnClient(nameof(MySqlDbFunctionsExtensions.Contains)),
                exNoLang.Message);

            var exLang = Assert.Throws <InvalidOperationException>(() => EF.Functions.Contains("teststring", "teststring", 1033));

            Assert.Equal(
                MySqlStrings.FunctionOnClient(nameof(MySqlDbFunctionsExtensions.Contains)),
                exLang.Message);
        }
        public void Throws_setting_identity_generation_for_invalid_type_only_with_explicit()
        {
            var propertyBuilder = CreateBuilder()
                                  .Entity(typeof(Splot), ConfigurationSource.Convention)
                                  .Property("Name", typeof(string), ConfigurationSource.Convention);

            Assert.False(
                propertyBuilder.MySql(ConfigurationSource.Convention)
                .ValueGenerationStrategy(MySqlValueGenerationStrategy.IdentityColumn));

            Assert.Equal(
                MySqlStrings.IdentityBadType("Name", nameof(Splot), "string"),
                Assert.Throws <ArgumentException>(
                    () => propertyBuilder.MySql(ConfigurationSource.Explicit).ValueGenerationStrategy(MySqlValueGenerationStrategy.IdentityColumn)).Message);
        }
Пример #19
0
        public void Throws_for_naked_type_name_on_property(string typeName)
        {
            var builder = CreateModelBuilder();

            var property = builder.Entity <StringCheese>()
                           .Property(e => e.StringWithSize)
                           .HasColumnType(typeName)
                           .Metadata;

            var mapper = CreateTypeMapper();

            Assert.Equal(
                MySqlStrings.UnqualifiedDataTypeOnProperty(typeName, nameof(StringCheese.StringWithSize)),
                Assert.Throws <ArgumentException>(() => mapper.FindMapping(property)).Message);
        }
Пример #20
0
        public void Throws_setting_sequence_generation_for_invalid_type()
        {
            var propertyBuilder = CreateBuilder()
                                  .Entity(typeof(Splot))
                                  .Property(typeof(string), "Name");

            Assert.Equal(
                MySqlStrings.SequenceBadType("Name", nameof(Splot), "string"),
                Assert.Throws <ArgumentException>(
                    () => propertyBuilder.HasValueGenerationStrategy(MySqlValueGenerationStrategy.SequenceHiLo)).Message);

            Assert.Equal(
                MySqlStrings.SequenceBadType("Name", nameof(Splot), "string"),
                Assert.Throws <ArgumentException>(
                    () => new PropertyBuilder((IMutableProperty)propertyBuilder.Metadata).UseHiLo()).Message);
        }
Пример #21
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 protected virtual void ValidateNonKeyValueGeneration([NotNull] IModel model)
 {
     foreach (var property in model.GetEntityTypes()
              .SelectMany(t => t.GetDeclaredProperties())
              .Where(
                  p => ((MySqlPropertyAnnotations)p.MySql()).GetMySqlValueGenerationStrategy(fallbackToModel: false)
                  == MySqlValueGenerationStrategy.SequenceHiLo &&
                  !p.IsKey() &&
                  p.ValueGenerated != ValueGenerated.Never &&
                  (!(p.FindAnnotation(MySqlAnnotationNames.ValueGenerationStrategy) is ConventionalAnnotation strategy) ||
                   !ConfigurationSource.Convention.Overrides(strategy.GetConfigurationSource()))))
     {
         throw new InvalidOperationException(
                   MySqlStrings.NonKeyValueGeneration(property.Name, property.DeclaringEntityType.DisplayName()));
     }
 }
Пример #22
0
        public void Throws_setting_identity_generation_for_invalid_type_only_with_explicit()
        {
            var propertyBuilder = CreateBuilder()
                                  .Entity(typeof(Splot))
                                  .Property(typeof(string), "Name");

            Assert.Equal(
                MySqlStrings.IdentityBadType("Name", nameof(Splot), "string"),
                Assert.Throws <ArgumentException>(
                    () => propertyBuilder.HasValueGenerationStrategy(MySqlValueGenerationStrategy.IdentityColumn)).Message);

            Assert.Equal(
                MySqlStrings.IdentityBadType("Name", nameof(Splot), "string"),
                Assert.Throws <ArgumentException>(
                    () => new PropertyBuilder((IMutableProperty)propertyBuilder.Metadata).UseIdentityColumn()).Message);
        }
Пример #23
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override void ValidateSharedColumnsCompatibility(IReadOnlyList <IEntityType> mappedTypes, string tableName)
        {
            base.ValidateSharedColumnsCompatibility(mappedTypes, tableName);

            var identityColumns  = new List <IProperty>();
            var propertyMappings = new Dictionary <string, IProperty>();

            foreach (var property in mappedTypes.SelectMany(et => et.GetDeclaredProperties()))
            {
                var propertyAnnotations = property.Relational();
                var columnName          = propertyAnnotations.ColumnName;
                if (propertyMappings.TryGetValue(columnName, out var duplicateProperty))
                {
                    var propertyStrategy          = property.MySql().ValueGenerationStrategy;
                    var duplicatePropertyStrategy = duplicateProperty.MySql().ValueGenerationStrategy;
                    if (propertyStrategy != duplicatePropertyStrategy &&
                        (propertyStrategy == MySqlValueGenerationStrategy.IdentityColumn ||
                         duplicatePropertyStrategy == MySqlValueGenerationStrategy.IdentityColumn))
                    {
                        throw new InvalidOperationException(
                                  MySqlStrings.DuplicateColumnNameValueGenerationStrategyMismatch(
                                      duplicateProperty.DeclaringEntityType.DisplayName(),
                                      duplicateProperty.Name,
                                      property.DeclaringEntityType.DisplayName(),
                                      property.Name,
                                      columnName,
                                      tableName));
                    }
                }
                else
                {
                    propertyMappings[columnName] = property;
                    if (property.MySql().ValueGenerationStrategy == MySqlValueGenerationStrategy.IdentityColumn)
                    {
                        identityColumns.Add(property);
                    }
                }
            }

            if (identityColumns.Count > 1)
            {
                var sb = new StringBuilder()
                         .AppendJoin(identityColumns.Select(p => "'" + p.DeclaringEntityType.DisplayName() + "." + p.Name + "'"));
                throw new InvalidOperationException(MySqlStrings.MultipleIdentityColumns(sb, tableName));
            }
        }
Пример #24
0
        public void Detects_non_key_SequenceHiLo(bool obsolete)
        {
            var modelBuilder = CreateConventionalModelBuilder();

            if (obsolete)
            {
#pragma warning disable 618
                modelBuilder.Entity <Dog>().Property(c => c.Type).ForMySqlUseSequenceHiLo();
#pragma warning restore 618
            }
            else
            {
                modelBuilder.Entity <Dog>().Property(c => c.Type).UseHiLo();
            }

            VerifyError(MySqlStrings.NonKeyValueGeneration(nameof(Dog.Type), nameof(Dog)), modelBuilder.Model);
        }
Пример #25
0
        public void Detects_indexed_include_properties(bool obsolete)
        {
            var modelBuilder = CreateConventionalModelBuilder();

            modelBuilder.Entity <Dog>().Property(c => c.Type);
            if (obsolete)
            {
#pragma warning disable 618
                modelBuilder.Entity <Dog>().HasIndex(nameof(Dog.Name)).ForMySqlInclude(nameof(Dog.Name));
#pragma warning restore 618
            }
            else
            {
                modelBuilder.Entity <Dog>().HasIndex(nameof(Dog.Name)).IncludeProperties(nameof(Dog.Name));
            }

            VerifyError(MySqlStrings.IncludePropertyInIndex(nameof(Dog), nameof(Dog.Name)), modelBuilder.Model);
        }
Пример #26
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override void ValidateSharedTableCompatibility(
            IReadOnlyList <IEntityType> mappedTypes, string tableName)
        {
            var firstMappedType   = mappedTypes[0];
            var isMemoryOptimized = firstMappedType.MySql().IsMemoryOptimized;

            foreach (var otherMappedType in mappedTypes.Skip(1))
            {
                if (isMemoryOptimized != otherMappedType.MySql().IsMemoryOptimized)
                {
                    throw new InvalidOperationException(
                              MySqlStrings.IncompatibleTableMemoryOptimizedMismatch(
                                  tableName, firstMappedType.DisplayName(), otherMappedType.DisplayName(),
                                  isMemoryOptimized ? firstMappedType.DisplayName() : otherMappedType.DisplayName(),
                                  !isMemoryOptimized ? firstMappedType.DisplayName() : otherMappedType.DisplayName()));
                }
            }

            base.ValidateSharedTableCompatibility(mappedTypes, tableName);
        }
Пример #27
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected virtual void ValidateIndexIncludeProperties([NotNull] IModel model)
        {
            foreach (var index in model.GetEntityTypes().SelectMany(t => t.GetDeclaredIndexes()))
            {
                var includeProperties = index.MySql().IncludeProperties;
                if (includeProperties?.Count > 0)
                {
                    var notFound = includeProperties
                                   .Where(i => index.DeclaringEntityType.FindProperty(i) == null)
                                   .FirstOrDefault();

                    if (notFound != null)
                    {
                        throw new InvalidOperationException(
                                  MySqlStrings.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(
                                  MySqlStrings.IncludePropertyDuplicated(index.DeclaringEntityType.DisplayName(), duplicate));
                    }

                    var inIndex = includeProperties
                                  .Where(i => index.Properties.Any(p => i == p.Name))
                                  .FirstOrDefault();

                    if (inIndex != null)
                    {
                        throw new InvalidOperationException(
                                  MySqlStrings.IncludePropertyInIndex(index.DeclaringEntityType.DisplayName(), inIndex));
                    }
                }
            }
        }
Пример #28
0
        public void Detects_multiple_identity_properties(bool obsolete)
        {
            var modelBuilder = CreateConventionalModelBuilder();

            modelBuilder.Entity <Dog>().Property(d => d.Id).ValueGeneratedNever();

            if (obsolete)
            {
#pragma warning disable 618
                modelBuilder.Entity <Dog>().Property(c => c.Type).UseMySqlIdentityColumn();
                modelBuilder.Entity <Dog>().Property <int?>("Tag").UseMySqlIdentityColumn();
#pragma warning restore 618
            }
            else
            {
                modelBuilder.Entity <Dog>().Property(c => c.Type).UseIdentityColumn();
                modelBuilder.Entity <Dog>().Property <int?>("Tag").UseIdentityColumn();
            }

            VerifyError(MySqlStrings.MultipleIdentityColumns("'Dog.Tag', 'Dog.Type'", nameof(Dog)), modelBuilder.Model);
        }
Пример #29
0
        private static void CheckValueGenerationStrategy(IProperty property, MySqlValueGenerationStrategy?value)
        {
            if (value != null)
            {
                var propertyType = property.ClrType;

                if (value == MySqlValueGenerationStrategy.IdentityColumn &&
                    !IsCompatibleIdentityColumn(property))
                {
                    throw new ArgumentException(
                              MySqlStrings.IdentityBadType(
                                  property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName()));
                }

                if (value == MySqlValueGenerationStrategy.ComputedColumn &&
                    !IsCompatibleComputedColumn(property))
                {
                    throw new ArgumentException(
                              MySqlStrings.ComputedBadType(
                                  property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName()));
                }
            }
        }
Пример #30
0
 /// <summary>
 ///     <para>
 ///         An implementation of the SQL MATCH operation for Full Text search.
 ///     </para>
 ///     <para>
 ///         The semantics of the comparison will depend on the database configuration.
 ///         In particular, it may be either case-sensitive or
 ///         case-insensitive.
 ///     </para>
 ///     <para>
 ///         Should be directly translated to SQL.
 ///         This function can't be evaluated on the client.
 ///     </para>
 /// </summary>
 /// <param name="_">The DbFunctions instance.</param>
 /// <param name="matchExpression">The property of entity that is to be matched.</param>
 /// <param name="pattern">The pattern against which Full Text search is performed</param>
 /// <param name="searchMode">Mode in which search is performed</param>
 /// <returns>true if there is a match.</returns>
 /// <exception cref="InvalidOperationException">Throws when query switched to client-evaluation.</exception>
 public static bool Match <T>(
     [CanBeNull] this DbFunctions _,
     [CanBeNull] T matchExpression,
     [CanBeNull] string pattern,
     MySqlMatchSearchMode searchMode)
 => throw new InvalidOperationException(MySqlStrings.FunctionOnClient(nameof(Match)));