public class User
{
public int ID { get; set; }
public string EmailAddress { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int ID { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string Postcode { get; set; }
}
class TestDbContext : DbContext
{
public TestDbContext()
: base("DefaultConnectionString")
{
}
public DbSet<User> Users { get; set; }
public DbSet<Address> Addresses { get; set; }
}
以上是模型定义和 DbContext 定义。我想为用户添加一个新地址,所以我编写了如下代码:
var context = new TestDbContext();
var user = context.Users.FirstOrDefault(item => item.ID == 1);
user.Addresses.Add(new Address()
{
City = "City",
Street = "Street",
Postcode = "Postcode",
});
context.SaveChanges();
我的疑问是为什么这段代码中执行了3个SQL查询?
它是在 FirstOrDefault 中生成的
SELECT TOP (1) [Extent1].[ID] AS [ID], [Extent1].[EmailAddress] AS [EmailAddress] FROM [dbo].[Users] AS [Extent1] WHERE 1 = [Extent1].[ID]
- 它是在 user.Addresses.Add 中生成的
exec sp_executesql N'SELECT [Extent1].[ID] AS [ID], [Extent1].[City] AS [City], [Extent1].[Street] AS [Street], [Extent1].[Postcode] AS [Postcode], [Extent1].[User_ID] AS [User_ID] FROM [dbo].[Addresses] AS [Extent1] WHERE ([Extent1].[User_ID] IS NOT NULL) AND ([Extent1].[User_ID] = @EntityKeyValue1)',N'@EntityKeyValue1 int',@EntityKeyValue1=1
它是在 SaveChanges 中生成的
exec sp_executesql N'INSERT [dbo].[Addresses]([City], [Street], [Postcode], [User_ID]) VALUES (@0, @1, @2, @3) SELECT [ID] FROM [dbo].[Addresses] WHERE @@ROWCOUNT > 0 AND [ID] = scope_identity()',N'@0 nvarchar(max) ,@1 nvarchar(max) ,@2 nvarchar(max) ,@3 int',@0=N'City',@1=N'Street',@2=N'Postcode',@3=1
如何避免第二条 SQL?
最佳答案
当您访问该属性(即 user.Addresses
)时,Addresses
导航属性会延迟加载,这就是您获得第二个 SQL 命令的原因。
尝试禁用延迟加载并查看是否有效(不要忘记在 User
的构造函数中初始化 Addresses
属性,例如:
public User()
{
Addresses = new HashSet<Address>();
}
关于c# - 使用 Entity Framework 进行级联插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21330165/