Либо получить локальную сущность, либо прикрепить новую - PullRequest
0 голосов
/ 07 июня 2018

Моя сущность выглядит следующим образом:

public class User
{
    public int Id {get; set;}
}

Я не хочу запрашивать базу данных каждый раз, когда у меня появляется конкретный пользователь, у которого, как я знаю, есть пользователь для этого идентификатора.Похоже, что Attach работает для этого случая, но если DbContext уже хранит объект для этого конкретного пользователя локально, он выдаст исключение.

Пример того, что я хочу сделать:

var user1 = ctx.GetLocalOrAttach(new User{Id = 1});
var user2 = ctx.GetLocalOrAttach(new User{Id = 2});
AddUserRelation(user1, user2);

Есть ликакое-то решение для этого?Если нет, то какой будет идеальный способ проверить, существует ли сущность локально.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Вы можете искать в свойстве DbSet<T>.Local, но это было бы неэффективно.

Лучшим способом для ИМО является использование пользовательского метода расширения FindTracked из моего ответа на Удалять загруженные и выгруженные объекты по идентификатору в EntityFrameworkCore

using Microsoft.EntityFrameworkCore.Internal;

namespace Microsoft.EntityFrameworkCore
{
    public static partial class CustomExtensions
    {
        public static TEntity FindTracked<TEntity>(this DbContext context, params object[] keyValues)
            where TEntity : class
        {
            var entityType = context.Model.FindEntityType(typeof(TEntity));
            var key = entityType.FindPrimaryKey();
            var stateManager = context.GetDependencies().StateManager;
            var entry = stateManager.TryGetEntry(key, keyValues);
            return entry?.Entity as TEntity;
        }
    }
}

, который похож на метод EF Core Find, но не загружает объект из базы данных, если он не существует локально.

Использование в вашем случае будет выглядеть так:

var user1 = ctx.FindTracked(1) ?? ctx.Attach(new User { Id = 1 }).Entity;
var user2 = ctx.FindTracked(2) ?? ctx.Attach(new User { Id = 2 }).Entity;
AddUserRelation(user1, user2);
0 голосов
/ 07 июня 2018

Я использую EF в течение многих лет, и я никогда не использовал механизм присоединения, он обычно только доставляет вам неприятности.
Если я посмотрю на код, я предполагаю, что вы хотите создать связь между 2пользовательские записи, но вы хотите оптимизировать производительность, не запрашивая обе пользовательские записи.(Лично мне было бы наплевать на 20 мс служебных данных, это стоило бы мне получить пользовательские объекты, но я думаю, это могло бы иметь значение).

Что позволяет EF создавать записи с внешними ключами без загрузки внешнихentity.
Таким образом, вы можете изменить следующий код с:

var user1 = context.Users.Find(1);
var user2 = context.Users.Find(2);
var userRelation = new UserRelation();
userRelation.FromUser = user1;
userRelation.ToUser = user2;
context.UserRelations.Add(userRelation);

на:

var userRelation = new UserRelation();
userRelation.FromUserId = 1;
userRelation.ToUserId = 2;
context.UserRelations.Add(userRelation);

Обратите внимание, что в моем последнем примере кода я не запрашивал оба объекта пользователя, ноEF создаст запись UserRelation с двумя действительными внешними ключами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...