the side one not many framework for first determined dependent could code child entity-framework code-first ef-code-first fluent-interface

entity framework - side - EF 4.1: diferencia entre.WithMany() y.WithOptional()?



entity framework one to one (1)

A continuación hay dos configuraciones de API fluidas similares:

Con muchas()

modelBuilder.Entity<Country>() .HasRequired(cou => cou.Currency) .WithMany() .WillCascadeOnDelete(false);

WithOptional ()

modelBuilder.Entity<Country>() .HasRequired(cou => cou.Currency) .WithOptional() .WillCascadeOnDelete(false);

Lo que estoy tratando de expresar aquí es: cada Country requiere una Currency concreta, pero una Currency puede tener cero, uno o muchos países asignados.

¿Cuál de las declaraciones anteriores tendré que usar? O en otras palabras: ¿Cuál es exactamente la diferencia entre los .WithMany() y .WithOptional() ?


Si su modelo se vería así:

public class Country { public int CountryId { get; set; } public Currency Currency { get; set; } } public class Currency { public int CurrencyId { get; set; } }

entonces ...

modelBuilder.Entity<Country>() .HasRequired(cou => cou.Currency) .WithOptional() .WillCascadeOnDelete(false);

... crea una relación de clave externa en la base de datos donde CountryId en la tabla Countries es la clave principal y la clave externa de la tabla CurrencyId de las Currencies al mismo tiempo, por lo que la tabla Countries tiene una sola columna CountryId . Un registro de Currencies puede vivir sin un registro de Countries relacionado. Pero si un registro de Currencies tiene un registro de Countries relacionado Countries entonces no más de uno porque la clave externa es CountryId que es la clave principal al mismo tiempo y, por lo tanto, solo puede estar en un registro. Entonces, la relación Currencies -> Countries es de 1-to-0...1 .

El otro ejemplo ...

modelBuilder.Entity<Country>() .HasRequired(cou => cou.Currency) .WithMany() .WillCascadeOnDelete(false);

... crea una segunda columna CurrencyId en la tabla Countries de la base de datos que no admite nulos y es una clave externa a la CurrencyId de la tabla de Currencies . Así que aquí es posible que un registro de Currencies no tenga un registro de Countries relacionado o uno o más de uno porque la clave externa ahora es otra columna, no idéntica a la clave principal. Por lo tanto, más de una fila en la tabla Countries puede tener la misma clave externa. La relación Currencies -> Countries aquí es de 1-to-0...n .

Editar

Si toma el siguiente código para los dos modelos configurados de forma diferente ...

Country country1 = new Country(); Country country2 = new Country(); Currency currency = new Currency(); country1.Currency = currency; country2.Currency = currency; context.Countries.Add(country1); context.Countries.Add(country2); context.SaveChanges();

... entonces funciona el segundo caso (.WithMany): obtenemos dos nuevos países y una moneda en la base de datos.

Sin embargo, un poco extraño es que en el segundo caso (.HasOptional) solo se almacena el primer País, el segundo simplemente se ignora. En realidad, esperaba obtener una excepción. No estoy seguro si eso tiene que ser considerado como un error.

Edit2

Cambiar el orden en el ejemplo anterior para ...

context.Countries.Add(country1); context.Countries.Add(country2); country1.Currency = currency; country2.Currency = currency;

... arroja la excepción esperada en el caso ".HasOptional".