使用DbContext设置()而不是在上下文中公开

执行以下操作时是否存在任何差异:

public class UsersContext : DbContext { public DbSet Users { get; set; } } 

与使用上下文的Set方法:

 public class UsersContext : DbContext { } var db = new UsersContext(); var users = db.Set(); 

这些有效地做了同样的事情,给了我一组用户,但是除了你没有通过属性暴露集合之外还有什么大的差别吗?

添加Users属性是为了方便,因此您不需要记住所有表的内容以及相应的类是什么,您可以使用Intellisense查看上下文旨在与之交互的所有表。 最终结果在function上等同于使用Set

使用Code-First迁移时,您可以从前一种方法中获益,因为将自动检测新实体。 否则,我很确定它们是等价的。

这是我设置我的通用dbSet的方法,工作得很好

 DbContext context = new MyContext(); DbSet dbSet = context.Set(); 

它是更明确的通用版本,例如

 DbContext context = new MyContext(); DbSet dbSet = context.Set(); 

无论哪种方式,它们是相同的(当TUser

我认为有一些区别。 让我在问题中使用示例。 假设我想基于User.FirstName和User.LastName做一个Any(User表有更多字段)

方法1: UsersContext.Users.Any(u => u.FirstName.ToLower() == userObj.FirstName && u.LastName.ToLower() == userObj.LastName);

方法2: (UsersContext.Set(typeof(User)) as IQueryable).Any(u => u.FirstName.ToLower() == userObj.FirstName && u.LastName.ToLower() == userObj.LastName);

我在sql profiler中检查了在Method1中触发的查询是:

  exec sp_executesql N'SELECT CASE WHEN ( EXISTS (SELECT 1 AS [C1] FROM [dbo].[User] AS [Extent1] WHERE (((LOWER([Extent1].[FirstName])) = (LOWER(@p__linq__0))) AND ((LOWER([Extent1].[LastName])) = @p__linq__1) )) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 1 AS [C1] FROM [dbo].[User] AS [Extent2] WHERE (((LOWER([Extent2].[FirstName])) = (LOWER(@p__linq__0))) AND ([Extent2].[LastName] = @p__linq__1) )) THEN cast(0 as bit) END AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]',@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'jack',@p__linq__1=N'saw' 

从方法2:

  SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Email] AS [Email], .......other fields...... FROM [dbo].[Users] AS [Extent1] 

该表有40000条记录,Method1大约需要20毫秒,而Method2需要大约3500毫秒。

我认为两种方法之间没有这样的区别,因为Set()更适合实现像Repository模式这样的数据访问模式,因为Set()方法的通用性质。