Entity Framework - Советы и лучшие практики - PullRequest
1 голос
/ 22 августа 2011

Я недавно начал с Entity Framework для проекта MVC, который я делаю, чтобы овладеть технологиями, и у меня есть несколько вопросов: ..

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

public bool SavePrank(PrankDefinition prank)
    {

        if (prank == null)
            throw new ArgumentNullException("prank");

        if (prank.ID == 0)
        {
            DataBase.Pranks.Add(prank);
            DataBase.SaveChanges();
        }
        else
        {
            DataBase.Pranks.Attach(prank);
            DataBase.Entry(prank).State = EntityState.Modified;
            DataBase.SaveChanges();
        }

        return true;

    }

Я также получил этот код для получения последней версии сущностей ..

public List<PrankDefinition> GetPranks()
    {
        List<PrankDefinition> pranks = DataBase.Pranks.Where(p => p != null).ToList();

        foreach (PrankDefinition prankDef in pranks)
        {
            DataBase.Entry(prankDef).Reload();
        }

        return pranks;
    }

причина, по которой мне пришлось вызывать .reload для объекта, заключается в том, что когда другой клиент использует проект - изменения в объекте не отражаются мгновенно (что очень важно). Мой вопрос для этого - есть ли лучший способ сделать это? Есть ли что-то, что я могу прикрепить к методу Where, чтобы получить последние версии?

мой контекст - если это поможет ..

    public static DataContext DataBase
    {
        get
        {
            if (HttpContext.Current != null &&            HttpContext.Current.Session["DataBase"]== null)
            {
                HttpContext.Current.Session["DataBase"] = new DataContext();
            }

            return HttpContext.Current.Session["DataBase"] as DataContext;
        }
        set
        {
            if (HttpContext.Current != null)
                HttpContext.Current.Session["DataBase"] = value;
        }
    }

любая помощь будет фантастической!

РЕДАКТИРОВАТЬ: ОБНОВЛЕНИЕ ДО КОНТЕКСТА ДАННЫХ

Будет ли это лучшей реализацией DataContext?

public static DataContext DataBase
    {
        get { return new DataContext(); }
    }

ура. Ste.

1 Ответ

4 голосов
/ 22 августа 2011

Несколько замечаний:

  • На мой взгляд SaveChanges завершает единицу работы и не относится к таким методам единого хранилища, как SavePrank. Я, вероятно, предпочел бы образец как это:

    InsertOrUpdatePrank(prank); // = SavePrank without SaveChanges
    ModifyPerhapsSomeOtherEntity(otherEntity);
    SetPerhapsRelationshipBetweenPrankAndOtherEntity(prank, otherEntity);
    // ... more ...
    DataBase.SaveChanges();
    

    Таким образом, все изменения записываются в базу данных за одну транзакцию.

  • Где вы располагаете своим контекстом? Если вы создаете экземпляр и сохраняете его в сеансе, но не располагаете контекстом в своем коде явно, контекст живет через несколько запросов. Это потенциальный источник больших проблем, поскольку ваш контекст может по-прежнему содержать сущности из более старых запросов при обработке нового запроса. Например: если prank с ID = 123 обновляется дважды в двух последующих запросах от одного и того же пользователя (в одном и том же сеансе), DataBase.Pranks.Attach(prank) вызовет исключение, поскольку при старом розыгрыше из предыдущих запросов с таким же идентификатором уже привязан к контексту. В веб-приложении контекст никогда не должен жить дольше, чем один запрос, чтобы избежать подобных проблем и многих других.

  • Если вы располагаете контекстом для запроса, я больше не вижу необходимости «перезагружать» сущности. Вы все равно должны загрузить объекты из базы данных, потому что каждый контекст является новым и пустым, когда вы вводите действие. Итак, перезагрузить нечего. В любом случае вы получите последнюю версию своих документов из базы данных при выполнении запросов.

  • Where(p => p != null) не имеет смысла. Чтобы получить все строки, вы можете написать:

    List<PrankDefinition> pranks = DataBase.Pranks.ToList();
    
...