Pergunta

Eu tenho um pai entidade

foo o que existe no banco de dados, eu tenho uma propriedade de bar nesta entidade (relação Um-para-muitos).

Foo é destacado, porque a sua desserializado usando WebApi, então eu faço isso para foo

context.Foos.AddOrUpdate(foo);

Mesmo Se houver uma nova bar referência anexado a ele, ele não vai ficar guardado, no entanto, ele faz um trabalho como este para uma outra relação que nós temos é uma relação muitos-para-Muitos.Se eu adicionar uma nova entidade para que a coleta será salvo para a sua mesa e também uma linha é adicionada à tabela de relação.

Se eu fizer context.Bars.AddOrUpdate(foo.Bar); antes de chamar context.Foos.AddOrUpdate(foo); ele vai salvar o novo bar corretamente para a mesa de bar, mas ele não vai adicionar o correto barId para o foo tabela

@Yuliam Chandra

Se eu entendi sua resposta corretamente (eu acho que você está misturando até bares e foos na sua resposta) isso deve funcionar?

var foo = new Foo();
foo.FooId = 524 //Existing foo;

foo.Bar = new Bar(); //Completely new bar    
db.Foos.AddOrUpdate(foo);
db.SaveChanges();

Mas ele não

Foi útil?

Solução

Trabalhar com objectos desligados necessidades de código extra.

Se você estiver trabalhando com desconectado objetos, você deve gerenciar manualmente a sincronização.

Origem

Se Bar é uma entidade existente que você precisa para anexá-lo primeiro, para que o Foo vai ser adicionado como Bar's crianças.

if (foo.Bar.Id != 0)
{
    context.Bars.Attach(foo.Bar);
    context.Foos.AddOrUpdate(foo);
}

O exemplo de código acima é semelhante com Course (Foo) e Department (Bar) exemplo este artigo.

Mas se Bar é uma nova entidade, você só precisa adicionar Foo, e , em seguida, Bar também será adicionado.

else
{
    context.Foos.Add(foo);
}

Alguma outra variedade pode ser verificado no minha resposta.

atualização

Antes de explicar melhor, eu gostaria de mostrar o código idêntico.

  • db.Set<T>().Add(instance) é igual a db.Entry(instance).State = EntityState.Added;
  • db.Set<T>().Attach(instance) é igual a db.Entry(instance).State = EntityState.Unchanged;

A resposta anterior explicou sobre duas condições.

  • Novo Foo e Bar existente

    context.Bars.Attach(foo.Bar);

    context.Foos.AddOrUpdate(foo);

  • Novo Foo e Bar novo

    context.Foos.Add(foo);

Especial Adicionados

Added tem condição especial, uma vez que uma entidade está marcada como Added.todas as entidades do gráfico será marcado como Added também, mesmo se qualquer entidade de referência é um objeto existente no banco de dados.Se temos este código, Foo e Bar será adicionado.

var foo = new Foo (); // new foo
foo.Bar = new Bar { BarId = 123 }; // existing bar
db.Set<Foo>().Add(foo);
db.SaveChanges();

Para evitar que isso aconteça, Bar precisa ser ligado primeiro.

var foo = new Foo (); // new foo
foo.Bar = new Bar { BarId = 123 }; // existing bar
db.Set<Bar>().Attach(bar);
db.Set<Foo>().Add(foo);
db.SaveChanges();

Seleção Julie Lerman artigo para mais explicação completa.

A razão pela qual isto acontece é que quando você usa o DbSet.O método Add (que é, Screencasts.Adicionar), não é apenas o estado de raiz entidade marcada "Acrescentou," mas tudo no gráfico que o contexto não era anteriormente ciente de que é marcado também Adicionados.Mesmo que o desenvolvedor pode estar ciente de que o Tópico possui um valor de Id, Entity Framework honre suas EntityState (Adicionado) e cria um comando Inserir banco de dados para o Tópico, independentemente da Identificação existente.

Ajustar A Explicação Com Base Na Sua Atualização

E a sua atualizado questão é sobre a atual Foo e Bar novo.Utilizar o seu código, o resultado não irá adicionar novos Bar e Foo existente não fazer uma relação com as novas Bar.

var foo = new Foo();
foo.FooId = 524 //Existing foo;

foo.Bar = new Bar(); //Completely new bar    
db.Foos.AddOrUpdate(foo);
db.SaveChanges();

Se nós adicionar manualmente a Barra junto com AddOrUpdate(foo), o resultado ainda não é como o esperado.O novo Bar será adicionado, mas o Foo não tem relação com a nova Barra.

db.Bars.Add(foo.Bar);
db.Foos.AddOrUpdate(foo);

O comportamento de AddOrUpdate é inconsistente.

Solução

Se você estiver trabalhando com desconectado objetos, você deve gerenciar manualmente a sincronização.

Este código deve funcionar em todas as condições.

  • Novo Foo e Bar Novo
  • Novo Foo e Bar Existente
  • Existente Foo e Bar Novo
  • Existente Foo e Bar Existente

Este código depende da identificação (id = 0 é uma nova entidade).

db.Entry(foo).State = 
       foo.FooId == 0 ? EntityState.Added : EntityState.Modified;
if (foo.Bar != null)
{
    db.Entry(foo.Bar).State = 
       foo.Bar.BarId == 0 ? EntityState.Added : EntityState.Modified;
                                                             ^^^
    // If you don't want to change the Bar while creating a relationship between
    // Foo and with existing Bar, you can change 
    // `EntityState.Modified` with `EntityState.Unchanged`
}
db.SaveChanges();

Relacionados AddOrUpdate, Eu acho que há uma questão aberta que pode ser encontrado aqui.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top