C# 使用 DbContext Set<T>() 而不是暴露在上下文中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13710883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:31:40  来源:igfitidea点击:

Using DbContext Set<T>() instead of exposing on the context

c#.netentity-frameworkef-code-firstdbcontext

提问by Dismissile

Are there any differences when doing the following:

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

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

versus using the Set<T>method of the context:

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

public class UsersContext : DbContext
{
}

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

These effectively do the same thing, giving me a set of Users, but are there any big differences other than you are not exposing the set through a property?

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

采纳答案by Servy

The Usersproperty is added for convenience, so you don't need to remember what all of your tables are and what the corresponding class is for it, you can use Intellisense to see all of the tables the context was designed to interact with. The end result is functionally equivalent to using Set<T>.

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

回答by PinnyM

You get a benefit with the former method when using Code-First migrations, as new entities will be detected as such automatically. Otherwise, I'm quite certain they are equivalent.

使用 Code-First 迁移时,前一种方法会带来好处,因为将自动检测到新实体。否则,我很确定它们是等效的。

回答by Behnam Esmaili

I think there is no such difference between two approaches except that Set<User>()is more suitable for implementing data access patterns like Repositorypattern because of the generic nature of the Set<T>()method.

我认为两种方法之间没有这种区别,只是由于方法的通用性质,Set<User>()它更适合实现像模式这样的数据访问模式。RepositorySet<T>()

回答by Travis J

This is how I set my generic dbSet, works just fine

这就是我设置通用 dbSet 的方式,效果很好

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

It is the generic version of something more explicit, such as

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

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

Either way, they are the same (when Tis User)

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

回答by maicalal

I think there is some difference. Let me use the example as in the question. Assume i want to do a Any based on User.FirstName and User.LastName (User table has more fields)

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

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

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

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

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

I checked in sql profiler the query fired in Method1 is:

我在 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'Hyman',@p__linq__1=N'saw'

From Method2:

从方法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]

The table has 40000 records and Method1 takes around 20 ms while Method2 takes around 3500 ms.

该表有 40000 条记录,方法 1 需要大约 20 毫秒,而方法 2 需要大约 3500 毫秒。

回答by sproketboy

One difference is that the Set method takes any type include non entities and it won't throw exceptions, only returning an empty set of that type. So you could mess up if you typed the wrong class name.

一个区别是 Set 方法接受任何类型,包括非实体,它不会抛出异常,只返回该类型的空集。所以如果你输入了错误的类名,你可能会搞砸。