IDbSetExtensions.AddOrUpdate и отношения - PullRequest
5 голосов
/ 19 марта 2012

IDbSetExtensions.AddOrUpdate предназначен для помощи в написании кода, который работает одинаково, независимо от того, пуста база данных или заполнена.Но для связывания объектов нужен другой код.Когда база данных пуста, у объектов еще нет идентификаторов, и вы связываете их, назначая свойство навигации.Однако, когда объекты уже существуют, навигационные свойства не работают, и вам необходимо установить внешние ключи напрямую. Навигационные свойства работают для прокси-серверов в обоих случаях за счет утраты POCO. Редактирование: На самом деле прокси-серверы не работают, когда обе сущности устарели.

Этот пример дает сбой во второмВызов SaveChanges, когда EF пытается установить CountryID в 0:

public class Country
{
    public virtual int ID { get; set; }
    public virtual string Name { get; set; }
}

public class Person
{
    public virtual int ID { get; set; }
    public virtual string Name { get; set; }

    public virtual int CountryID { get; set; }
    public virtual Country Country { get; set; }
}

public class Context : DbContext
{
    public DbSet<Person> Person { get; set; }
    public DbSet<Country> Country { get; set; }
}

class Program
{
    static void Foo()
    {
        using (var db = new Context())
        {
            //var c = new Country();
            var c = db.Country.Create();
            c.Name = "usa";
            db.Country.AddOrUpdate(x => x.Name, c);

            //var p = new Person();
            var p = db.Person.Create();
            p.Name = "billg";
            p.Country = c;
            db.Person.AddOrUpdate(x => x.Name, p);

            db.SaveChanges();
        }
    }
    static void Main()
    {
        Database.SetInitializer<Context>(new DropCreateDatabaseAlways<Context>());
        Foo();
        Foo();
    }
}

Как используется AddOrUpdate?

1 Ответ

9 голосов
/ 20 марта 2012

IDbSetExtensions.AddOrUpdate предназначен для помощи в написании кода, который работает одинаково, независимо от того, пуста база данных или заполнена.

AddOrUpdate предназначен для использования только в Seed методе первой миграции кода. Он не должен использоваться в обычном коде, потому что имеет большие накладные расходы и некоторые ограничения. Накладные расходы - это дополнительный запрос к базе данных и рефлексия. Ограничение состоит в том, что он проверяет только основную сущность, которую вы передаете, но не ее отношения. Каждое отношение должно обрабатываться отдельным вызовом AddOrUpdate:

static void Foo()
{
    using (var db = new Context())
    {
        var c = new Country() {Name = "abc"};
        db.Country.AddOrUpdate(x => x.Name, c);

        var p = new Person()
        {
            Name = "me",
            CountryID = c.ID,
            Country = c 
        };

        db.Person.AddOrUpdate(x => x.Name, p);
        db.SaveChanges();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...