web-dev-qa-db-ja.com

コンテキストで公開する代わりにDbContext Set <T>()を使用する

次のことを行うときに違いはありますか?

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

これらは事実上同じことを行い、ユーザーのセットを提供しますが、プロパティを通じてセットを公開しないこと以外に大きな違いはありますか?

29
Dismissile

Usersプロパティは便宜上追加されているため、すべてのテーブルが何であるか、および対応するクラスが何であるかを覚えておく必要はありません。Intellisenseを使用して、コンテキストが設計されたすべてのテーブルを確認できます対話する。最終結果は、機能的にはSet<T>を使用することと同等です。

16
Servy

新しいエンティティは自動的に検出されるため、コードファーストの移行を使用すると、前者の方法でメリットが得られます。そうでなければ、私はそれらが同等であると確信しています。

5
PinnyM

多少の違いはあると思います。質問の例を使用してみましょう。 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プロファイラーで確認した方法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'

Method2から:

    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レコードがあり、Method2は約3500ミリ秒、Method1は約20ミリ秒かかります。

2
maicalal

これは私が私の一般的なdbSetを設定する方法であり、うまく機能します

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

これは、より明確なものの一般的なバージョンです。

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

どちらにしても、それらは同じです(TUserの場合)

2
Travis J

1つの違いは、Setメソッドは非エンティティを含むすべての型を受け取り、例外をスローせず、その型の空のセットのみを返すことです。したがって、間違ったクラス名を入力すると、失敗する可能性があります。

1
sproketboy

Set<User>()メソッドの一般的な性質のため、Set<T>()Repositoryパターンのようなデータアクセスパターンの実装により適していることを除いて、2つのアプローチにはそのような違いはないと思います。

0
Behnam Esmaili