IDbSetExtensions.AddOrUpdate and Relationships

IDbSetExtensions.AddOrUpdate is designed to write code that works the same way, regardless of whether the database is empty or full. But to link objects you need different code. When the database is empty, the objects do not yet have identifiers, and you bind them by assigning a navigation property. However, if objects already exist, the navigation properties do not work, and you need to set foreign keys directly. Navigation properties really work for proxies in both cases due to the confiscation of POCOs. Edit: In fact, proxies do not work when both objects are out of date.

This pattern falls in a second SaveChanges call when EF tries to set CountryID to 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();
    }
}

How is AddOrUpdate used?

+5
1

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();
    }
}
+9

All Articles