[英]LINQ check if a list contains any item from another list mysql syntax error
I'm using LINQ with MySql我在 MySql 中使用 LINQ
Mysql version: 5.7.21-log
Mysql 版本:
5.7.21-log
EntityFramework : v6.0.0.0
v6.0.0.0
: v6.0.0.0
Mysql.Data : v6.9.12.0
Mysql.Data :
v6.9.12.0
MySql.Data.Entity.EF6: v6.9.12.0
(I'm not using MySql.Data.Entity
) MySql.Data.Entity.EF6:
v6.9.12.0
(我没有使用MySql.Data.Entity
)
Query询问
var keywords = new List<string>();
keywords.Add("keyword1");
var query = dbContext.ads.Where(x => keywords.Any(y => x.Title.Contains(y)));
Explanation ads
is a table in database, sample data:说明
ads
是数据库中的一个表,示例数据:
Get records where Title
contains any of the keyword
获取
Title
包含任何keyword
Exception例外
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%keyword1%))) AS `GroupBy1`' at line 10
Complete Exception:完全异常:
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> MySql.Data.MySqlClient.MySqlException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%keyword1%)' at line 10
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.EntityFramework.EFMySqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
--- End of inner exception stack trace ---
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at ExamBuilder.Controllers.ExamController.EnterExam()
Internal SQL query内部 SQL 查询
SELECT
`Extent1`.`packageMasterId`,
`Extent1`.`title`,
`Extent1`.`packageStatus`,
`Extent1`.`packageCreationDate`,
`Extent1`.`basePrice`,
`Extent1`.`validity`
FROM `package_master` AS `Extent1`
WHERE EXISTS(SELECT
1 AS `C1`
FROM (SELECT
1 AS `X`) AS `SingleRowTable1`
WHERE `Extent1`.`tile` LIKE %keyword1%)
How can I modify the query to get those recrods whose title
contains any of the keyword
?如何修改查询以获取
title
包含任何keyword
?
Update:更新:
Question is not duplicate The linked question uses same query that I have used but i'm getting exception with mysql!问题不重复链接的问题使用与我使用过的相同的查询,但我遇到了 mysql 异常!
I've managed to reproduce your error with the versions of Entity Framework
and MySql.Data.*
libraries.我已经设法用
Entity Framework
和MySql.Data.*
库的版本重现了您的错误。 Bumping the version to the highest 6.*.*
available could not help, so here is my workaround using the SqlQuery
.将版本提高到可用的最高
6.*.*
无济于事,所以这是我使用SqlQuery
解决方法。
var keywords = new List<string>() { "Test123", "TestASD" };
var likeStatements = keywords.Select(keyword => $"title LIKE '%{keyword}%'");
var whereClauseBody = string.Join(" OR ", likeStatements.ToArray());
var query = context.Ads
.SqlQuery($"select * from stack_linq.ads where {whereClauseBody};");
Notes:笔记:
stack_linq
is the schema name. stack_linq
是架构名称。 Change it to your schema name.<connectionStrings>
then the SqlQuery
can be changed to $"select ads where ...
<connectionStrings>
默认指定了架构名称,则可以将SqlQuery
更改为$"select ads where ...
title LIKE ...
change the name of the column (eg if it should be Title
instead of title
)title LIKE ...
更改列的名称(例如,如果它应该是Title
而不是title
)App.config
file:App.config
文件:<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="StackMySqlContext" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=stack_linq;uid=root;password=mysql" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.12.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"></provider>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.12.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
</configuration>
Links I've found useful to setup the MWE :我发现对设置MWE有用的链接:
Used Visual Studio version: Community 2017 (15.9.5)使用的 Visual Studio 版本:Community 2017 (15.9.5)
如果我正确理解您正在寻找的内容,则以下内容应该有效...
query = db.ads.Where(x => keywords.Contains(x.title));
I ran into the same bug with MySql.Data.Entity
v6.10.9
.我遇到了与
MySql.Data.Entity
v6.10.9
相同的错误。 Oddly, it only happened when the array had only 1 value.奇怪的是,它只发生在数组只有 1 个值时。 If my array had two or more values, it generated the correct SQL.
如果我的数组有两个或多个值,它会生成正确的 SQL。 Therefore, my method ended up looking something like:
因此,我的方法最终看起来像:
var query = null;
if (1 == keywords.Length) {
// MySql.Data.Entity bug creates invalid SQL with only one value
var keyword = keywords[0];
query = dbContext.ads.Where(x => x.Title.Contains(keyword)));
}
else {
query = dbContext.ads.Where(x => keywords.Any(y => x.Title.Contains(y)));
}
try this:尝试这个:
query = db.ads.Where(x => x.Title.Contains(x.Keywords));
or:或者:
var title= db.ads.Select(x=>x.title).ToList();
query = db.ads.Where(x => title.Contains(x.keyword));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.