【EFCORE笔记】添加数据的多种方案
每个上下文实例都有一个 ChangeTracker,它负责跟踪需要写入数据库的更改。 更改实体类的实例时,这些更改会记录在 ChangeTracker 中,然后在调用 SaveChanges 时被写入数据库。 此数据库提供程序负责将更改转换为特定于数据库的操作(例如,关系数据库的 INSERT、UPDATE 和DELETE 命令)。
ChangeTracker
提供对上下文所有实体状态的跟踪信息。
EntityEntry
表示给定实体的跟踪信息,可通过 ChangeTracker.Entries 、 DbContext.Entry 和 DbSet.Entry 获取。
EntityState
被跟踪实体的状态
状态演练
查询一个对象,观察跟踪和未跟踪情况下对象的状态。
_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; Blog blog = _context.Find<Blog>(1) ; EntityEntry entityEntry = _context.Entry(blog);
添加数据
添加数据是指:数据库无记录,添加新的记录到数据库。
DbContext.Add() 或 DbSet.Add()
开始跟踪给定实体,将尚未被跟踪的任何实体更改为已添加状态。 Detached=>Added
更 多 重 载 :AddAsync 、 AddRange 和 AddRangeAsync
https://www.cnblogs.com/CreateMyself/p/9043744.html
DbContext.Attach() 或 DbSet.Attach()
开始在上下文中跟踪给定的实体,将执行导航属性的递归搜索以查找尚未被上下文跟踪的可到达实体。
这些实体也将开始被上下文跟踪。通俗点来讲就是查找所有 Detached 游离状态的对象图,将其设置为被上下文跟踪的状态,跟踪起来,跟踪成何种状态,有以下两种情况
如果可访问实体的主键值已设置,则将以“未更改”状态跟踪它。Detached=>Unchanged
如果未设置主键值,则将在 “已添加”状态下跟踪它。Detached=>Added
批处理此操作:AttachRange
Blog blog = new Blog() { Name = "zeroblog", Url = "www.xcode.me" };
EntityEntry entityEntry = _context.Entry(blog); Console.WriteLine(entityEntry.State);
_context.Attach(blog); Console.WriteLine(entityEntry.State);
_context.SaveChanges(); Console.WriteLine(entityEntry.State);
添加新实体的关系图
var blog = new Blog
{
Name = "zerodo",
Url = "www.xcode.me",
Posts = new List<Post>
{
new Post { Title = "Intro to C#" },
new Post { Title = "Intro to VB.NET" },
new Post { Title = "Intro to F#" }
}
};
_context.Blogs.Add(blog);
//_context.Blogs.Attach(blog);
_context.SaveChanges();
注意无法插入数据的情况
var blog = new Blog
{
Name = "zerodo",
Url = "www.xcode.me",
};
var posts = new List<Post>
{
new Post { Title = "Intro to C#",Blog=blog },
new Post { Title = "Intro to F#",Blog=blog }
};
await _context.AddAsync(blog); await _context.SaveChangesAsync();
添加相关实体
var blog = _context.Blogs.Include(b => b.Posts).First();
var post = new Post { Title = "Intro to EF Core" };
blog.Posts.Add(post);
_context.SaveChanges();
关于自增主键数据的强行插入
var blog1 = new Blog { BlogId = 33, Name = "zerodo1", Url = " www.xcode1.me", };
var blog2 = new Blog { BlogId = 44, Name = "zerodo2", Url = " www.xcode2.me", };
var blog3 = new Blog { BlogId = 55, Name = "zerodo3", Url = " www.xcode3.me", };
_context.Add(blog1);
_context.Add(blog2);
_context.Add(blog3);
_context.Database.OpenConnection(); try
{
_context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [Blogs] ON");
await _context.SaveChangesAsync();
_context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [Blogs] OFF");
}
finally
{
_context.Database.CloseConnection();
}
允许将显式值插入到表的标识列中。
当多次调用插入数据时,最后执行 SaveChanges 保存时,将生成批处理语句,而不像之前版本的EF那样,生成多条 SQL 语句,相比之下, EF Core 性能更高。
var blog1 = new Blog { Name = "zerodo1", Url = "www.xcode1.me", };
var blog2 = new Blog { Name = "zerodo2", Url = "www.xcode2.me", };
var blog3 = new Blog { Name = "zerodo3", Url = "www.xcode3.me", };
_context.Add(blog1);
_context.Add(blog2);
_context.Add(blog3);
_context.SaveChanges();
What is Batching of Statement in Entity Framework Core?
使用存储过程或者原生SQL保存数据
_context.Database.ExecuteSqlCommand("SQL");


浙公网安备 33010602011771号