Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用DbContext集<;T>;()而不是暴露在上下文中_C#_.net_Entity Framework_Ef Code First_Dbcontext - Fatal编程技术网

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

C# 使用DbContext集<;T>;()而不是暴露在上下文中,c#,.net,entity-framework,ef-code-first,dbcontext,C#,.net,Entity Framework,Ef Code First,Dbcontext,执行以下操作时是否存在任何差异: public class UsersContext : DbContext { public DbSet<User> Users { get; set; } } public类用户上下文:DbContext { 公共数据库集用户{get;set;} } 与使用上下文的Set方法相比: public class UsersContext : DbContext { } var db = new UsersContext(); var us

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

public class UsersContext : DbContext
{
    public DbSet<User> Users { get; set; }
}
public类用户上下文:DbContext
{
公共数据库集用户{get;set;}
}
与使用上下文的
Set
方法相比:

public class UsersContext : DbContext
{
}

var db = new UsersContext();
var users = db.Set<User>();
public类用户上下文:DbContext
{
}
var db=新用户上下文();
var users=db.Set();

这些方法有效地实现了同样的功能,为我提供了一组用户,但除了不通过属性公开该组用户之外,还有什么大的区别吗?

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

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

这就是我设置泛型dbSet的方式,很好用

DbContext context = new MyContext();
DbSet<T> dbSet = context.Set<T>();
DbContext context=newmycontext();
DbSet DbSet=context.Set();
它是更明确的东西的通用版本,例如

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

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

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

我认为有一些区别。 让我用问题中的例子。 假设我想基于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))为IQueryable).Any(u=>u.FirstName.ToLower()==userObj.FirstName&&u.LastName.ToLower()==userObj.LastName)

我签入了sql探查器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方法采用任何类型,包括非实体,它不会抛出异常,只返回该类型的空集。因此,如果键入错误的类名,您可能会陷入困境。

我没有想到迁移!是的,我知道通用存储库的用途在哪里,但我很好奇它是否有缺点。呃……好吗?我理解它是如何工作的。我想知道区别/限制是什么。@Dismissible-没有限制或区别,只是您可以通过使用泛型定义并传入类型来保存一些重复的代码。Set应该是return always single instance,以说明没有限制或区别,对吗?查看反编译的源代码,DbSet在DbContext的每个实例中都是相同的实例(例如,如果多次调用context.Set(),则会得到对相同DbSet的相同引用,假设“context”从未更改过实例)。这是在DbContext内部的InternalContext中完成的(它使用类型作为键保存一个内部字典)。@abatishchev Nope有一个Set methodSet可以接受一个泛型参数。Try Set().Any(…)@Dismissile我试过Set().Any(),它有同样的行为。你当时做了一件非常奇怪的事情,因为这三个方法都为我生成了相同的查询。@Dismissile你是对的。我发现了奇怪的部分。在Method2的情况下,即Set().Any(…),我传递的表达式类似于
ValidationMethod(u=>u.FirstName.ToLower()==userObj.FirstName&&u.LastName.ToLower()==userObj.LastName)
此实习生将执行
Set().Any(…表达式作为参数传递)
不确定确切原因。还在找呢。Will update.am跟踪问题用户只能是一个实例,而在上下文中,我想知道Set方法,是否也返回单个实例?您想要哪一个?您可以使用System.Linq.Dynamic。db.Set().Single(“Id=@0”,someId);只要主键是用户对象或您查询的任何对象上的Id。