2012-02-20 9 views
8

Estoy practicando con un conjunto de clases de código primero con una relación padre-hijo entre ellas.Uso de EF 4.1 Inserción de un registro principal y múltiples registros secundarios como una sola "Unidad de trabajo"

public class Parent 
{ 
    public int Id (get; set; } 
    public string Name { get; set; } 
    public List<Child> Children { get; set; } 

    public Parent() 
    { 
     Children = new List<Child>(); 
    } 
} 

public class Child() 
{ 
    public int Id (get; set; } 
    public string Name { get; set; } 
} 

public class MyContext : DbContext 
{ 
    public DbSet<Parent> Parents { get; set; } 
    public DbSet<Child> Children { get; set; } 
} 

En una aplicación de consola simple, creo un padre y creo dos registros secundarios y los agrego al padre. Si luego llamo a SaveChanges(), solo se agrega el primer niño a la tabla de niños.

var x = new MyContext(); 

var c1 = new Child { Name = "Alpha-Child" }; 
var c2 = new Child { Name = "Beta-Child" }; 

var p = new Parent {Name = "Alpha-Parent"}; 

p.Children.Add(c1); 
p.Children.Add(c2); 

x.Parents.Add(p); 

x.SaveChanges(); 

Bueno, eso no era lo que quería, así que traté de agregar quizá entonces tanto el objeto principal y el objeto de contexto.

var x = new MyContext(); 

var c1 = new Child { Name = "Alpha-Child" }; 
var c2 = new Child { Name = "Beta-Child" }; 

var p = new Parent {Name = "Alpha-Parent"}; 

p.Children.Add(c1); 
p.Children.Add(c2); 

x.Children.Add(c1); 
x.Children.Add(c2); 

x.Parents.Add(p); 

x.SaveChanges(); 

que consiguió tanto los registros secundarios en la base de datos, pero sólo uno de ellos (el primero) se asoció con el registro padre.

Por último, pero no menos importante, traté de hacer una llamada a SaveChanges() después de cada llamada a Parent.Add().

var x = new MyContext(); 

var c1 = new Child { Name = "Alpha-Child" }; 
var c2 = new Child { Name = "Beta-Child" }; 

var p = new Parent {Name = "Alpha-Parent"}; 

x.Parents.Add(p); 

p.Children.Add(c1); 
x.SaveChanges(); 

p.Children.Add(c2); 
x.SaveChanges(); 

Pero esto rompe mi idea de cómo funciona el Patrón de "Unidad de trabajo". I "debe ser capaz de llamar a SaveChanges() una vez, y tienen todas mis cambios tienen lugar, ¿verdad?

Entonces, ¿qué estoy haciendo mal?

Respuesta

6

El siguiente fragmento de código, salvo en los cambios individuales guardar. y siempre utilizar un TransactionScope guardar en un solo lote.

public class Child 
{ 
    public int Id (get; set; } 
    public string Name { get; set; } 
    public Parent Parent {set;get;} 
} 


var x = new MyContext(); 
var c1 = new Child { Name = "Alpha-Child" }; 
var c2 = new Child { Name = "Beta-Child" }; 

var p = new Parent {Name = "Alpha-Parent"}; 
c1.Parent = p; 
c2.Parent = p; 
x.Parents.Add(p); 
x.SaveChanges(); 
+0

Gracias. Eso funciona Pero, ¿por qué * NECESITO * un enlace de regreso al padre? En un mundo POCO regular, nunca crearía ese tipo de relación a menos que un requisito comercial lo necesitara. Siempre comenzaba a caminar por mis entidades con la entidad base. ¿Me estoy perdiendo algún Patrón que debo aprender/tomar en serio? – saunderl

+0

No, no necesita agregar propiedad para Parent in Chind. La propiedad de Parnet.Children es suficiente para una relación de uno a muchos. – Ray

+2

Solo una actualización: para hacer que se requiera Parent FK en la tabla Children, necesité agregar el enlace al padre del niño y usar una anotación para marcarlo como obligatorio. Pero, podría hacer que la propiedad sea privada para que quede oculta para los usuarios de la clase. – saunderl

2

no sé por qué se hereda de baseEntidad ya que ha mencionado que se está probando con el código POCO primer lugar. de todos modos, he probado con el siguiente código de éxito

class Program 
    { 
     static void Main(string[] args) 
     { 
      var x = new MyContext(); 

      var c1 = new Child { Name = "Alpha-Child" }; 
      var c2 = new Child { Name = "Beta-Child" }; 

      var p = new Parent { Name = "Alpha-Parent" }; 

      p.Children.Add(c1); 
      p.Children.Add(c2); 

      x.Parents.Add(p); 

      x.SaveChanges(); 


      Console.Read(); 
     } 
    } 

    public class Parent 
    { 
     public Parent() 
     { 
      Children = new List<Child>(); 
     } 

     public int Id { get; set; } 
     public string Name { get; set; } 
     public List<Child> Children { get; set; } 
    } 

    public class Child 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

    public class MyContext : DbContext 
    { 
     public DbSet<Parent> Parents { get; set; } 
     public DbSet<Child> Children { get; set; } 
    } 
+0

EntityBase ... un artefacto de cortar y pegar. He arreglado mi ejemplo. – saunderl

Cuestiones relacionadas