老婆出轨 发表于 2024-6-9 14:45:52

【Entity Framework】EF中DbSet类详解

【Entity Framework】EF中DbSet类详解



https://img-blog.csdnimg.cn/direct/1ba5440bb7a4489cb97963e4f50b7e71.png#pic_center
一、概述

DbSet可用于查询和生存的TEntity实例。针对的DbSet LINQ查询将转换为针对数据库的查询。
大概不会反映上下文中尚未生存到数据库的更改。如:结果将不包罗新添加的实体,而且大概扔包罗标记为要删除的实体。
根据所使用的数据库,针对DbSet的LINQ查询的某些部分大概在内存中求值,而不是转换为数据库查询。DbSet对象通常从DbSet派生DbContext的或方法Set()上的属性获取。
   Entity Framework Core不支持在同一DbContext实例上运行多个并行利用。这包罗异步查询的并行实行以及从多个线程进行的任何显示并发使用。
二、界说DbSet

使用Code First工作流进行开发时,可界说一个派生DbContext,用于表示与数据库的会话,并为模型中的每个范例公开一个DbSet。
2.1 具有DbSet属性的DbContext

Code First 示例中所示的常见环境是拥有一个具有公共自动 DbSet 属性的 DbContext,用于模型的实体范例。 例如:
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}
当在 Code First 模式下使用时,这会将 Blogs 和 Posts 设置为实体范例,并设置可从此访问的其他范例。 此外,DbContext 会自动调用这些属性的资源库来设置相应的 DbSet 的实例。
2.2 具有 IDbSet 属性的 DbContext

在某些环境下,例如创建 mocks 或 fakes 时,使用接口来声明 set 属性会更有效。 在这种环境下,可以使用 IDbSet 接口取代 DbSet。 例如:
public class BloggingContext : DbContext
{
    public IDbSet<Blog> Blogs { get; set; }
    public IDbSet<Post> Posts { get; set; }
}
此上下文的工作方式与使用 DbSet 类作为其 set 属性的上下文完全相同。
2.3 具有 IDbSet 属性的 DbContext

如果你不希望为 DbSet 或 IDbSet 属性公开公共资源库,则可以改为创建只读属性并自行创建 set 实例。 例如:
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs
    {
      get { return Set<Blog>(); }
    }

    public DbSet<Post> Posts
    {
      get { return Set<Post>(); }
    }
}
   请留意,DbContext 将缓存从 Set 方法返回的 DbSet 的实例,使每个属性在每次调用时都返回相同的实例。Code First 实体范例的发现工作方式与具有公共 Getter 和资源库的属性的工作方式相同。
三、DbSet属性

序号属性名阐明1EntityType与此IEnitityType集关联的元数据2Local获取一个,LocalView它表示此集中所有“已添加”、“未更改”和“修改”实体的本地视图。 四、DbSet方法

序号方法名阐明1Add将给定实体以“已添加”状态添加到集的基础上下文中,如许一来,当调用 SaveChanges 时,会将该实体插入到数据库中2AddAsync将给定实体聚集添加到基础化集的上下文中(每个实体都置于“已添加”状态),如许当调用 SaveChanges 时,会将它插入到数据库中3AsNoTracking返回一个新查询,此中返回的实体将不会在 DbContext 中进行缓存. (继承自 DbQuery)4Attach将给定实体附加到集的基础上下文中. 也就是说,将实体以“未更改”的状态放置到上下文中,就好像从数据库读取了该实体一样5Create为此集的范例创建新的实体实例. 请留意此实例不会添加或附加到此集. 如果基础上下文设置为创建代理且实体范例满足创建代理的要求,则返回的实例将是一个代理6Equals确定指定的 DbSet 是否等于当前 DbSet. (重写 DbQuery.Equals(Object).)7Find查找带给定主键值的实体. 如果上下文中存在带给定主键值的实体,则立即返回该实体,而不会向存储区发送请求. 否则,会向存储区发送查找带给定主键值的实体的请求,如果找到该实体,则将其附加到上下文并返回.如果未在上下文或存储区中找到实体,则返回 null8FindAsync异步查找带给定主键值的实体. 如果上下文中存在带给定主键值的实体,则立即返回该实体,而不会向存储区发送请求. 否则,会向存储区发送查找带给定主键值的实体的请求,如果找到该实体,则将其附加到上下文并返回. 如果未在上下文或存储区中找到实体,则返回 null9Include指定要包括在查询结果中的相关对象. (继承自 DbQuery)10Remove将给定实体标记为“已删除”,如许一来,当调用 SaveChanges 时,将从数据库中删除该实体. 请留意,在调用此方法之前,该实体必须以另一种状态存在于该上下文中11RemoveRange从基础化集的上下文中删除给定实体聚集(每个实体都置于“已删除”状态),如许当调用 SaveChanges 时,会从数据库中删除它12SqlQuery创建一个原始 SQL 查询,该查询将返回此集中的实体. 默认环境下,上下文会跟踪返回的实体;可通过对返回的 DbSqlQuery 五、DbContext动态生成DbSet

平时我们在使用EF的过程中,都是有DbContext中每一个表加一个DbSet,如果我们一个项目有上千个表,就得加上千个DbSet,是很贫苦的一个工程,现在采用一个简单的方法处理,在DbContext类的OnConfiguring方法中加上如下代码:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
      var assembly = Assembly.GetExecutingAssembly();
      foreach (Type type in assembly.ExportedTypes)
      {
         if (type.IsClass && type != typeof(EntityBase) && typeof(EntityBase).IsAssignableFrom(type))
         {
               var method = modelBuilder.GetType().GetMethods().Where(x => x.Name == "Entity").FirstOrDefault();
               if (method != null)
               {
                     method = method.MakeGenericMethod(new Type[] { type });
                     method.Invoke(modelBuilder, null);
               }
            }
      }
      base.OnModelCreating(modelBuilder);
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【Entity Framework】EF中DbSet类详解