.net 使用DbContext Set< T>()而不是在上下文上公开

cqoc49vn  于 2023-02-06  发布在  .NET
关注(0)|答案(7)|浏览(154)

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

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>();

它们实际上做了同样的事情,给了我一个用户集,但是除了不通过属性公开用户集之外,还有什么大的区别吗?

y53ybaqx

y53ybaqx1#

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

lf3rwulv

lf3rwulv2#

在使用Code-First迁移时,前一种方法会给您带来好处,因为新的实体会被自动检测出来,否则,我非常肯定它们是等效的。

lb3vh1jj

lb3vh1jj3#

这就是我设置通用数据库集的方式,工作正常

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

它是更显式内容的泛型版本,例如

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

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

8iwquhpp

8iwquhpp4#

一个不同之处是Set方法接受任何类型,包括non实体,它不会抛出异常,只返回该类型的空集,所以如果你键入了错误的类名,你可能会陷入混乱。

yjghlzjz

yjghlzjz5#

我认为两者有一些区别。让我使用问题中的例子。假设我想基于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<User>).Any(u => u.FirstName.ToLower() == userObj.FirstName && u.LastName.ToLower() == userObj.LastName);
我在sql profiler中检查了方法1中激发的查询:

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条记录,方法1大约需要20毫秒,而方法2大约需要3500毫秒。

8fsztsew

8fsztsew6#

我认为这两种方法之间没有这样的区别,除了Set<User>()更适合于实现像Repository模式这样的数据访问模式,因为Set<T>()方法具有泛型特性。

d4so4syb

d4so4syb7#

他们都做同样的事情

context.Set<T>(); 
    context.Set<User>()

,第一个是通用的,第二个是用户实体。这是我的简单答案和我所知道的?

相关问题