Tôi sẽ kiểm tra nó trước để chắc chắn. Hiệu suất không phải là quá tệ.
Nếu bạn cần nhập tất cả các hàng trong một giao dịch, hãy gọi nó sau tất cả lớp AddToClassName. Nếu các hàng có thể được nhập độc lập, hãy lưu các thay đổi sau mỗi hàng. Tính nhất quán của cơ sở dữ liệu là quan trọng.
Lựa chọn thứ hai tôi không thích. Sẽ rất khó hiểu đối với tôi (từ góc độ người dùng cuối cùng) nếu tôi thực hiện nhập vào hệ thống và nó sẽ từ chối 10 hàng trong số 1000, chỉ vì 1 hàng xấu. Bạn có thể thử nhập 10 và nếu không thành công, hãy thử từng cái một rồi đăng nhập.
Kiểm tra nếu mất nhiều thời gian. Đừng viết 'đáng tin cậy'. Bạn chưa biết điều đó. Chỉ khi nó thực sự là một vấn đề, hãy nghĩ đến giải pháp khác (marc_s).
BIÊN TẬP
Tôi đã thực hiện một số bài kiểm tra (thời gian tính bằng mili giây):
10000 hàng:
SaveChanges () sau 1 hàng: 18510,534
SaveChanges () sau 100 hàng: 4350,3075
SaveChanges () sau 10000 hàng: 5233,0635
50000 hàng:
SaveChanges () sau 1 hàng: 78496,929
SaveChanges () sau 500 hàng: 22302,2835
SaveChanges () sau 50000 hàng: 24022,8765
Vì vậy, thực sự cam kết sau n hàng sẽ nhanh hơn tất cả.
Khuyến nghị của tôi là:
- SaveChanges () sau n hàng.
- Nếu một lần cam kết không thành công, hãy thử lần lượt để tìm hàng bị lỗi.
Các lớp kiểm tra:
BÀN:
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]
Lớp học:
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);
}
}