Ich würde es zuerst testen, um sicher zu sein. Die Leistung muss nicht so schlecht sein.
Wenn Sie alle Zeilen in einer Transaktion eingeben müssen, rufen Sie sie nach der gesamten AddToClassName-Klasse auf. Wenn Zeilen unabhängig eingegeben werden können, speichern Sie die Änderungen nach jeder Zeile. Die Datenbankkonsistenz ist wichtig.
Zweite Option mag ich nicht. Es wäre für mich (aus Sicht des Endbenutzers) verwirrend, wenn ich in das System importieren würde, und es würde 10 von 1000 Zeilen ablehnen, nur weil 1 schlecht ist. Sie können versuchen, 10 zu importieren. Wenn dies fehlschlägt, versuchen Sie es nacheinander und melden Sie sich dann an.
Testen Sie, ob es lange dauert. Schreiben Sie nicht "wahrscheinlich". Du weißt es noch nicht. Denken Sie nur dann an eine andere Lösung (marc_s), wenn es sich tatsächlich um ein Problem handelt.
BEARBEITEN
Ich habe einige Tests durchgeführt (Zeit in Millisekunden):
10000 Zeilen:
SaveChanges () nach 1 Zeile: 18510.534
SaveChanges () nach 100 Zeilen: 4350,3075
SaveChanges () nach 10000 Zeilen: 5233,0635
50000 Zeilen:
SaveChanges () nach 1 Zeile: 78496.929
SaveChanges () nach 500 Zeilen: 22302,2835
SaveChanges () nach 50000 Zeilen: 24022,8765
Es ist also tatsächlich schneller, nach n Zeilen festzuschreiben als nach allem.
Meine Empfehlung lautet:
- SaveChanges () nach n Zeilen.
- Wenn ein Commit fehlschlägt, versuchen Sie es nacheinander, um eine fehlerhafte Zeile zu finden.
Testklassen:
TABELLE:
CREATE TABLE [dbo].[TestTable](
[ID] [int] IDENTITY(1,1) NOT NULL,
[SomeInt] [int] NOT NULL,
[SomeVarchar] [varchar](100) NOT NULL,
[SomeOtherVarchar] [varchar](50) NOT NULL,
[SomeOtherInt] [int] NULL,
CONSTRAINT [PkTestTable] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Klasse:
public class TestController : Controller
{
private readonly Random _rng = new Random();
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private string RandomString(int size)
{
var randomSize = _rng.Next(size);
char[] buffer = new char[randomSize];
for (int i = 0; i < randomSize; i++)
{
buffer[i] = _chars[_rng.Next(_chars.Length)];
}
return new string(buffer);
}
public ActionResult EFPerformance()
{
string result = "";
TruncateTable();
result = result + "SaveChanges() after 1 row:" + EFPerformanceTest(10000, 1).TotalMilliseconds + "<br/>";
TruncateTable();
result = result + "SaveChanges() after 100 rows:" + EFPerformanceTest(10000, 100).TotalMilliseconds + "<br/>";
TruncateTable();
result = result + "SaveChanges() after 10000 rows:" + EFPerformanceTest(10000, 10000).TotalMilliseconds + "<br/>";
TruncateTable();
result = result + "SaveChanges() after 1 row:" + EFPerformanceTest(50000, 1).TotalMilliseconds + "<br/>";
TruncateTable();
result = result + "SaveChanges() after 500 rows:" + EFPerformanceTest(50000, 500).TotalMilliseconds + "<br/>";
TruncateTable();
result = result + "SaveChanges() after 50000 rows:" + EFPerformanceTest(50000, 50000).TotalMilliseconds + "<br/>";
TruncateTable();
return Content(result);
}
private void TruncateTable()
{
using (var context = new CamelTrapEntities())
{
var connection = ((EntityConnection)context.Connection).StoreConnection;
connection.Open();
var command = connection.CreateCommand();
command.CommandText = @"TRUNCATE TABLE TestTable";
command.ExecuteNonQuery();
}
}
private TimeSpan EFPerformanceTest(int noOfRows, int commitAfterRows)
{
var startDate = DateTime.Now;
using (var context = new CamelTrapEntities())
{
for (int i = 1; i <= noOfRows; ++i)
{
var testItem = new TestTable();
testItem.SomeVarchar = RandomString(100);
testItem.SomeOtherVarchar = RandomString(50);
testItem.SomeInt = _rng.Next(10000);
testItem.SomeOtherInt = _rng.Next(200000);
context.AddToTestTable(testItem);
if (i % commitAfterRows == 0) context.SaveChanges();
}
}
var endDate = DateTime.Now;
return endDate.Subtract(startDate);
}
}