C# 为什么我的EntityFramework插入速度如此之慢?
我发现应用程序中的一个瓶颈是一个特定实体的插入操作(通过导航属性插入到三个表中)。这些类别的定义如下:C# 为什么我的EntityFramework插入速度如此之慢?,c#,entity-framework,C#,Entity Framework,我发现应用程序中的一个瓶颈是一个特定实体的插入操作(通过导航属性插入到三个表中)。这些类别的定义如下: public class TrackerState { public int Id { get; set; } [Index] public int TrackerId { get; set; } [Index] public DateTime DateRecorded { get; set; } public DateTime DatePub
public class TrackerState
{
public int Id { get; set; }
[Index]
public int TrackerId { get; set; }
[Index]
public DateTime DateRecorded { get; set; }
public DateTime DatePublished { get; set; }
public DateTime DateReceived { get; set; }
public LocationStatus LocationStatus { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public double Altitude { get; set; }
public double Accuracy { get; set; }
public string Source { get; set; }
public double Speed { get; set; }
public double Heading { get; set; }
public int PrimaryOdometer { get; set; }
public int SecondaryOdometer { get; set; }
public int OperationalSeconds { get; set; }
public virtual IList<AnalogState> AnalogStates { get; set; }
public virtual IList<DigitalState> DigitalStates { get; set; }
}
public class AnalogState
{
public int TrackerStateId { get; set; }
public virtual TrackerState TrackerState { get; set; }
public int Index { get; set; }
public int Value { get; set; }
}
public class DigitalState
{
public int TrackerStateId { get; set; }
public virtual TrackerState TrackerState { get; set; }
public int Index { get; set; }
public bool Value { get; set; }
}
仅这一部分就占了大部分时间。插入7个条目需要3秒钟。在一个事务中保存所有数字状态会产生巨大的差异:
if (trackerState.DigitalStates.Count > 0)
{
var query = "INSERT INTO DigitalStates ([TrackerStateId], [Index], [Value]) VALUES "
+ string.Join(",", trackerState.DigitalStates.Select(state => String.Format("({0}, {1}, {2})", entity.Id, state.Index, state.Value ? 1 : 0)));
context.Database.ExecuteSqlCommand(query);
}
出于某种原因,让Entity Framework自动添加集合似乎是针对添加的每个数字状态向数据库发出请求,尽管我的印象是它应该是一个事务,由上下文的
SaveChanges()
方法触发。此修复已将其从线性时间更改为相对于集合大小的近似恒定时间。现在我的下一个问题是,为什么?是否涉及任何验证?如最大值等?如果您尝试打开SQL Server Profiler并看到EF正在运行的查询需要15秒怎么办?据我所知,输入列上没有验证。您在上面的模型中看到的正是用于生成表的内容(除了复合键之外)。您是否向查询添加了记录器并查看了SQL执行的内容。还有,您运行的是什么版本的core或6?我用它来查看您的查询-简单易用。强烈推荐。
context.Database.ExecuteSqlCommand("INSERT INTO DigitalStates ([TrackerStateId], [Index], [Value]) VALUES (@Id, @Index, @Value)",
new SqlParameter("Id", entity.Id),
new SqlParameter("Index", digital.Index),
new SqlParameter("Value", digital.Value));
if (trackerState.DigitalStates.Count > 0)
{
var query = "INSERT INTO DigitalStates ([TrackerStateId], [Index], [Value]) VALUES "
+ string.Join(",", trackerState.DigitalStates.Select(state => String.Format("({0}, {1}, {2})", entity.Id, state.Index, state.Value ? 1 : 0)));
context.Database.ExecuteSqlCommand(query);
}