Simple bulk delete using EntityFramework.Extended throws syntax error - c#

I am using Entity Framework 6.1.1 with MySQL 5.6.24 and I want to bulk delete a large set of records.
I am using EntityFramework.Extended to improve performance.
However my first, very simple update query already fails:
DbContext.Tickets.Where(t => t.EventID == targetEvent.EventID).Delete();
This throws an AggregateException in mscolib, the inner Exception is a MySQLException:
[MySqlException (0x80004005): 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 '[youreal_TicketPlatform].[Tickets]
FROM [youreal_TicketPlatform].[Tickets] AS j' at line 1]
MySql.Data.MySqlClient.MySqlStream.ReadPacket() +501
MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId) +444
MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force) +136
MySql.Data.MySqlClient.MySqlDataReader.NextResult() +1254
MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) +2626
MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() +137
EntityFramework.Batch.<InternalDelete>d__0`1.MoveNext() +1350
Has anyone experienced this same error? What is the easiest way to see the actual query being performed? Adding a listener on DbContext.Database.Log doesn't show the query.
Basically I want to bulk remove large sets of data without having to retrieve them first.

I came across this issue and had found the solution. Just change the default BatchRunner of the Locator from SqlServerBatchRunner to MySqlBatchRunner and it will work with MySQL.
EntityFramework.Locator.Current.Register<EntityFramework.Batch.IBatchRunner>(
() => new EntityFramework.Batch.MySqlBatchRunner());
The related code in repository:
https://github.com/loresoft/EntityFramework.Extended/blob/master/Source/EntityFramework.Extended/Locator.cs
The related issue:
https://github.com/loresoft/EntityFramework.Extended/issues/163

I'm sure it's because you are using mysql. None of the Bulk tools for EF I know works with mysql. And if you look in source/Database for Extended it only contains SqlServer and SqlCompact.
You can write the Sql yourself and execute that through Entityframework.

Related

Wrong "Duplicate entry '284093' for key 'PRIMARY'" message

Preamble: This question may be useful to people who get wrong error messages when using MySQL. Proof is given that the error message is wrong.
In a MySQL database (version 5.7.18), MyISAM table "sensorhistory" has a column "id" of type "int(11)" with Extra "auto_increment". Data are inserted from an application written in C#. The INSERT query does NOT write the id column directly, of course. That's what the "auto_increment" is for. The table contains further 30 fields of float and varchar types, resp., plus a DateTime(3). The parameterized query is long.
I receive following error message:
Duplicate entry '284093' for key 'PRIMARY'
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, 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.MySqlClient.MySqlCommand.ExecuteNonQuery()
at DataStorage.SensorHistoryDatastore.StoreSensorHistory(IReadOnlyList'1 _reports, Boolean _canRetry) in C:\Users\bernhard.hiller\SVN\Product-SW\trunk\C_DataStorage\PhysicalContainers\SensorHistoryDatastore.cs:line 84
Oddly, when I execute SELECT max(id) FROM sensorhistory in MySQL Workbench, I get a maximum value of 284092, i.e. 1 less than the "duplicate entry". That is proof that the error message is wrong.
I'd like to know how such an odd error can occur, and how to fix it.
Addendum:
An "Analyze table" in MySQL Workbench showed that the table is corrupt:
Found key at page 6585344 that points to record outside datafile
It could be repaired with a simple Repair table sensorhistory
I am still interested in how that corruption of the table can have occured.
By the way: a big THANK YOU to all those DOWNVOTERS who seem to be unable to read the text: this is not a f***ing stupid question about a "duplicate key", because I showed proof that the duplicate value does not exist at all!
Addendum 208-09-12:
The error re-occured after just 1 day, same table, same error message (just with a new value).
The Windows Eventlog showed more than 7 crashes between Sep 7 and Sep 11 (id 6008: "The previous system shutdown was unexpected"). The newest entry in the table sensorhistory was shortly before such crash in both cases.
The crashes ended on Sep 11 in the morning. I do not know the reason - other people are working on that test machine too. There were no more database issues then.
I conclude that a sudden Windows crash caused some inconsistency in the database, which then lead to that error message.

mysql Error:13 MyISAM table file not found

I have a set of files (around 20MB each) that needs to be inserted into a table in mysql. The insert is done in a loop for all files (single threaded). This works usually fine, but from time to time I am getting the following exception: File '.table.MYD' not found (Errcode: 13) for one file in the middle of the set (the first 50 ran ok, next 2-3 will fail and then the following will run fine again). If I just re-run the queries for the failed files in mysql workbench (or re-run the failed ones), they are working fine. The table is just created, with no indexes - so problems like 'index failed', table fragmentation or any other problems should not be there.
Below is the complete stacktrace:
File '.dbtable.MYD' not found (Errcode: 13)
----------------------------------
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int32& 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.MySqlClient.MySqlCommand.ExecuteNonQuery()
at Utils.SqlUtils.ExecMysql(String sql, String connection)
at Utils.MySqlExecQueue.DoExec(Object data)
----------------------------------
MySql.Data
where:
+ ExecMysql - looks like
using (MySqlConnection cnn = new MySqlConnection(connection))
{
cnn.Open();
using (MySqlCommand cmd = new MySqlCommand(sql, cnn))
{
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
+DoExec is a method that pics the files from a queue, creates the sql statement and calls ExecMysql above.
+the inserting code and mysql are on the same machine (Windows 2008, x64);
+there are no antiviruses or any other tool running on that machine that may lock the table file (as found on some blogs);
+the c# (.net 4) code is using mysql connector 6.5.4, the mysql version is 5.5;
I have implemented a dummy workaround like 'try-to-insert-while-13error-exception-is-thrown' but I have a strong feeling that this is not the correct solution.
Any ideea what is going on and how to fix this issue once and for all?
UPDATE - Clearly, the 'try-to-insert-while-13error-exception-is-thrown' fix is not a good ideea: I just got the same exception while running a SELECT on the table right after succesfully inserted data.
UPDATE 2 - checked the logs and I have noticed another wierd exception: Error on rename of '.\db\table.MYD' to '.\db\#sql2-4e4-1677.MYD' (Errcode: 17) ... things are getting better ...
do you have any anti-virus? If so make sure the mysql directory and its temp folder are excluded from AV and try again.

Entity Framework with SQLite exception: The underlying provider failed on Commit

I'm using the Entity Framework (.NET 4.0) with SQLite as the underlying database and I get an exception when I try to commit some changes to the database:
The underlying provider failed on Commit.
The stack trace is:
System.Data.EntityException: The underlying provider failed on Commit. ---> System.Data.SQLite.SQLiteException: The database file is locked
database is locked
at System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt)
at System.Data.SQLite.SQLiteDataReader.NextResult()
at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavi
or behave)
at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery()
at System.Data.SQLite.SQLiteTransaction.Commit()
at System.Data.EntityClient.EntityTransaction.Commit()
--- End of inner exception stack trace ---
at System.Data.EntityClient.EntityTransaction.Commit()
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at MySystem.MySystemService.UpdateFollowersAndUsers() in C:\Path\To\MySystem\MySystemService.cs:line 295
My code is pretty simple:
// Gets more followers for the competitor and updates the database
List<Follower> moreFollowers = GetMoreFollowers(competitor);
// Add the new followers to the database
using (MySystemEntities db = new MySystemEntities())
{
try
{
foreach (Follower f in moreFollowers)
{
db.AddToFollowers(f);
}
db.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
This snippet of code is inside MyService, it comes in with a batch of 5,000 followers and it's getting the above exception. However, when I pull the same snippet of code out into the Main function and just manually add a few followers, then it no longer throws the exception and the followers are successfully added to my database. Apparently the database file is locked, what may be causing this issue?
I just found out the answer in another SO question: 'The database file is locked' with System.Data.SQLite
Ironically, the OP answers his own question too :).

Invalid Month in Date - Date format in Informix reverts sporadically

So we have an AIX (ugh) server that runs an ERP system. This system's built in reports suck so I am of course tasked with building the reports we need.
I've got many reports I run and most of course are for specific dates, etc. The coding is done in C# running in ASP.net on a Windows 2003 Standard Server box. It uses the Informix CSDK to connect via the .Net Data Adapter that comes with the CSDK. The server runs Informix 10 on the AIX 5.2 server.
What's weird is that anytime we start and stop Informix or reboot the server, etc, it seems that Informix decides to change the way it's handled the date via the CSDK. If it's currently expecting MM/DD/YYYY then it'll eventually decide after the above situation that is wants it in YYYY/MM/DD. This usually ends up giving me an "Invalid Month in Date" error. Then I go into my dateformat function (made to easily allow me to fall back and forth) and manually change it over. A couple reports I built in the handling of this error and then retry the same query with the other format of the date. This of course is less than ideal and I'd like to get to the bottom of it!
Here is some pasted text from the ASP.net page error. Thanks!
Server Error in '/' Application.
ERROR [HY000] [Informix .NET provider][Informix]Invalid month in date
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about theerror and where it originated in the code.
Exception Details: IBM.Data.Informix.IfxException: ERROR [HY000] [Informix .NET provider][Informix]Invalid month in date
Source Error:
Line 479:
Line 480: //aUsage = new IfxDataAdapter(sSelect_Usage, conn);
Line 481: aUsage.Fill(dsUsage, "Usage");
Line 482: aUsage.Dispose();
Line 483: dtUsage = dsUsage.Tables["Usage"];
Source File: D:\Inetpub\reports2.oscarwinski.com\App_Code\IMRShipClass.cs Line: 481
Stack Trace:
[IfxException: ERROR [HY000] [Informix .NET provider][Informix]Invalid month in date]
IBM.Data.Informix.IfxConnection.HandleError(IntPtr hHandle, SQL_HANDLE hType, RETCODE retcode) +26
IBM.Data.Informix.IfxCommand.ExecuteReaderObject(CommandBehavior behavior, String method) +654
IBM.Data.Informix.IfxCommand.ExecuteReader(CommandBehavior behavior) +117
IBM.Data.Informix.IfxCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior) +4
System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) +130
System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) +287
System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable) +92
IMRShipClass.Generate() in D:\Inetpub\reports2.oscarwinski.com\App_Code\IMRShipClass.cs:481
IMRShip.testIMR() in D:\Inetpub\reports2.oscarwinski.com\IMRShip.aspx.cs:114
IMRShip.btnExport2Excel_Click1(Object sender, EventArgs e) in D:\Inetpub\reports2.oscarwinski.com\IMRShip.aspx.cs:259
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +111
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +110
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565
Version Information: Microsoft .NET Framework Version:2.0.50727.3082; ASP.NET Version:2.0.50727.3082
The date format is controlled by the client, not the server. Obviously it has a default (US format), but each client can dictate the format it wishes to use. This is done by setting the DBDATE environment variable. (There is also GL_DATE if you're using locales.)
If the date format has switched, you should check the value of this environment variable. Is it being set by your middleware in some circumstances?
Urgh! .NET is not my strong point - you may have to adapt what I say to work correctly.
On Windows, for better or worse, there is an Informix utility called SETNET32 which can be used to set Informix-related environment variables for Windows programs that connect to Informix databases. You don't mention whether you've set anything using this. Investigate whether it used by the Informix .NET provider.
You also do not mention whether the IDS server instance on the AIX box is restarted when the problem appears. I assume not. (The analysis might be different if it did.)
The main environment variable that controls the date format is DBDATE. It takes various notations, such as:
DBDATE=dmy4/ # 30/07/2009
DBDATE=mdy4/ # 07/30/2009
DBDATE=y4md- # 2009-07-30
DBDATE=mdy20 # 073009
Don't use the last one. If there are changes in the value of DBDATE, this could account some of your problems, and setting DBDATE would probably fix your problems.
There are other variables that affect date interpretation if DBDATE is not set; these include CLIENT_LOCALE and DB_LOCALE, and even GL_DATE. However, DBDATE has the highest priority and is the one most people set most usually.
This is probably unrelated, but I was receiving the same error. I ended up changing the single quotes in my SQL to parentheses. I was using parameterized SQL.
SELECT id, descriptor FROM Foo WHERE descriptor >= '?'
becomes
SELECT id, descriptor FROM Foo WHERE descriptor >= (?)
This may not be the case for your particular setup, but I have seen servers change the date format reported to databases when administrators have had their locale set to something differnt to the default, but only while they are logged in!
You may wish to check the country/locale settings for EVERY user on the system.
DB2/Informix overrides the client date format. You contact your Db2 admin and set the date format in the server side once for all. We faced exactly same problem in AS400 (DB2) and DB admin never accepted it as in your case. Once the ISO date format syntax was taken from IBM site and given to DB2 admin he changed it. After that our programs worked fine with dates.
Good luck.
Set DBDATE=MDY4/ in the client app that runs the reports and every other client as well.
Start the informix instance as root instead of informix user .... it solves my pb and my night lol

How do I update a change using SubSonic and MySQL

I was trying to TDD using SubSonic 2.1, MySQL and C# and when I got to testing updating an existing record using the code below,
public void Test2()
{
User.Insert("jmarcus1", "jmarcus1", "jackass", "marcus", 3, false);
User users = new User();
int ulevel = 1;
User.Update(2, "jmarcus1", "jmarcus1", "jackass", "marcus", ulevel, false);
Assert.AreEqual(1, users.Ulevel);
}
with the following
------ Test started: Assembly: SalMan.dll ------
Starting the MbUnit Test Execution
Exploring SalMan, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
MbUnit 2.4.2.130 Addin
Found 3 tests
[success] TestFixture1.Test
[success] TestFixture1.Test1
[failure] TestFixture1.Test2
TestCase 'TestFixture1.Test2'
failed: 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 'WHERE `userid` = 1; SELECT 1 AS id' at line 1
MySql.Data.MySqlClient.MySqlException
Message: 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 'WHERE `userid` = 1; SELECT 1 AS id' at line 1
Source: MySql.Data
StackTrace:
at MySql.Data.MySqlClient.MySqlStream.OpenPacket()
at MySql.Data.MySqlClient.NativeDriver.ReadResult(UInt64& affectedRows, Int64& lastInsertId)
at MySql.Data.MySqlClient.MySqlDataReader.GetResultSet()
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteScalar()
C:\svn\subsonicproject\trunk\SubSonic\DataProviders\MySqlDataProvider.cs(280,0): at SubSonic.MySqlDataProvider.ExecuteScalar(QueryCommand qry)
C:\svn\subsonicproject\trunk\SubSonic\DataProviders\DataService.cs(533,0): at SubSonic.DataService.ExecuteScalar(QueryCommand cmd)
C:\svn\subsonicproject\trunk\SubSonic\ActiveRecord\ActiveRecord.cs(182,0): at SubSonic.ActiveRecord`1.Save(String userName)
D:\My Documents\Visual Studio 2008\Projects\SalMan\SalMan\Generated\User.cs(352,0): at Salman.User.Update(Int32 varUserid, String varUsername, String varPassword, String varFname, String varLname, Int32 varUlevel, Boolean varStatus)
D:\My Documents\Visual Studio 2008\Projects\SalMan\SalMan\Tests\TestFixture1.cs(40,0): at salman.TestFixture1.Test2()
[reports] generating HTML report
TestResults: file:///C:/Documents%20and%20Settings/*****************/Application%20Data/MbUnit/Reports/SalMan.Tests.html
2 passed, 1 failed, 0 skipped, took 7.66 seconds.
Does anyone have a workaround for this?
It looks to me like your args are out of order. The PK should be the first thing - are you sure they are lining up correctly?
Are you using ActiveRecord? If so - have you tried this:
User u=new User();
u.UserName("jmarcus1");
u.Name="jackass"
u.Ulevel=1;
...
u.Save();
User u=new User("jmarcus1");
u.UILevel=2;
u.Save();
apparently the solution was, following Robs excellent advice above, to
User u = User.FetchByID(2);
u.Ulevel = ulevel;
u.save();
i was not too sure that the snippet above would work for updates until you specify
the record you wish to update.
my question to Rob however is, why does "u.Update(2, "jmarcus",..." give the error
above?

Categories