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

时间:2012-12-04 19:58:12

标签: c# .net entity-framework ef-code-first dbcontext

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

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

与使用上下文的Set<T>方法相比:

public class UsersContext : DbContext
{
}

var db = new UsersContext();
var users = db.Set<User>();

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

6 个答案:

答案 0 :(得分:16)

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

答案 1 :(得分:5)

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

答案 2 :(得分:2)

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

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

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

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

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

答案 3 :(得分:2)

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

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

方法2:(UsersContext.Set(typeof(User)) as IQueryable<User>).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毫秒。

答案 4 :(得分:1)

一个区别是Set方法采用任何类型,包括非实体,并且不会引发异常,仅返回该类型的空集合。因此,如果您输入了错误的类名,可能会搞砸。

答案 5 :(得分:0)

我认为除了Set<User>()更适合实现Repository模式等数据访问模式之外,两种方法之间没有这种差异,因为Set<T>()方法具有通用性。< / p>