Подтвердить что ты не робот

Использование 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>();

Они эффективно делают то же самое, предоставляя мне набор пользователей, но есть ли какие-то большие различия, кроме того, что вы не подвергаете заданию через свойство?

4b9b3361

Ответ 1

Свойство Users добавлено для удобства, поэтому вам не нужно запоминать, что все ваши таблицы и что для него соответствует соответствующему классу, вы можете использовать Intellisense для просмотра всех таблиц, в которых был сконструирован контекст для взаимодействия. Конечный результат функционально эквивалентен использованию Set<T>.

Ответ 2

Вы получаете выгоду от прежнего метода при использовании переходов Code-First, поскольку новые сущности будут обнаружены как автоматически. В противном случае я вполне уверен, что они эквивалентны.

Ответ 3

Вот как я устанавливаю свой общий dbSet, отлично работает

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

Это общая версия чего-то более явного, например

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

В любом случае, они одинаковы (когда T есть User)

Ответ 4

Я думаю, что есть какая-то разница. Позвольте мне использовать пример, как в вопросе. Предположим, что я хочу сделать Any на основе User.FirstName и User.LastName(в таблице пользователя больше полей)

Метод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 запрос, запущенный в 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 мс.

Ответ 5

Я думаю, что нет никакой разницы между двумя подходами, кроме того, что Set<User>() более подходит для реализации шаблонов доступа к данным, таких как шаблон Repository из-за общего характера метода Set<T>().