History
I have a list of "records" (3500) that I save in XML and compress when I exit the program. Because:
- the number of entries is increasing
- only need to update about 50 records on exit
- Saving takes about 3 seconds.
I needed another solution - an embedded database. I chose SQL CE because it works with VS without any problems and the license is fine for me (I compared it with Firebird , SQLite , EffiProz , db4o and BerkeleyDB ).
Data
Record structure: 11 fields, of which 2 are the primary key (nvarchar + byte). Other entries are bytes, data, double and ints.
I do not use any relationships, joins, indexes (except the primary key), triggers, views, etc. This flat dictionary is actually Key + Value pairs. I modify some of them, and then I have to update them in the database. From time to time I add new "records", and I need to store (insert) them. It's all.
LINQ Approach
I have an empty database (file), so I do 3500 inserts in a loop (one after the other). I donโt even check if the record exists because db is empty.
Lead time? 4 minutes, 52 seconds. I fainted (note: XML + compress = 3 seconds).
SQL CE Raw Approach
I did a bit of work with Google, and despite such claims as here: LINQ to SQL (CE) speed compared to SqlCe saying that it was SQL CE itself, I gave it a try.
The same cycle, but this time the inserts are performed using the SqlCeResultSet (DirectTable mode, see Bulk Insertion in SQL Server CE ) and SqlCeUpdatableRecord.
Result? Are you sitting still? Well ... 0.3 seconds (yes, a split second!).
Problem
LINQ is very readable, and raw operations are exactly the opposite. I could write a mapper that translates all column indices into meaningful names, but it seems that it is inventing the wheel - after all, this has already been done in ... LINQ.
So maybe this is a way to tell LINQ to speed things up? QUESTION - how to do it?
The code
LINQ
foreach (var entry in dict.Entries.Where(it => it.AlteredByLearning)) { PrimLibrary.Database.Progress record = null; record = new PrimLibrary.Database.Progress(); record.Text = entry.Text; record.Direction = (byte)entry.dir; db.Progress.InsertOnSubmit(record); record.Status = (byte)entry.LastLearningInfo.status.Value;
Unprocessed operations
SqlCeCommand cmd = conn.CreateCommand ();
cmd.CommandText = "Progress"; cmd.CommandType = System.Data.CommandType.TableDirect; SqlCeResultSet rs = cmd.ExecuteResultSet (ResultSetOptions.Updatable);
foreach (var entry in dict.Entries.Where(it => it.AlteredByLearning)) { SqlCeUpdatableRecord record = null; record = rs.CreateRecord(); int col = 0; record.SetString(col++, entry.Text); record.SetByte(col++,(byte)entry.dir); record.SetByte(col++,(byte)entry.LastLearningInfo.status.Value);