entity-framework linq-to-entities duplicates entity-framework-4.3.1

Cómo evitar la inserción duplicada en Entity Framework 4.3.1



entity-framework linq-to-entities (1)

Tengo un modelo pequeño creado utilizando el enfoque de primer código: una clase de City que contiene solo información sobre el nombre de la ciudad.

public class City { public City() { Posts = new List<Post>(); } public City(string cityName) { Name = cityName; } public virtual ICollection<Post> Posts { get; private set; } public int Id { get; set; } public string Name { get; private set; } }

Una clase Post representa una combinación de código postal y referencia de la ciudad

public class Post { public virtual City City { get; set; } public int Id { get; set; } public string ZipCode { get; set; } }

ambas entidades tienen sus conjuntos definidos en contexto como sus configuraciones

public DbSet<City> Cities { get; set; } public DbSet<Post> Posts { get; set; } modelBuilder.Configurations.Add(new CityMap()); modelBuilder.Configurations.Add(new PostMap()); public class CityMap : EntityTypeConfiguration<City> { public CityMap() { // Primary Key HasKey(t => t.Id); // Properties // Table & Column Mappings ToTable("City"); Property(t => t.Id).HasColumnName("Id"); Property(t => t.Name).HasColumnName("Name"); } } public class PostMap : EntityTypeConfiguration<Post> { public PostMap() { // Primary Key HasKey(t => t.Id); // Properties // Table & Column Mappings ToTable("Post"); Property(t => t.Id).HasColumnName("Id"); Property(t => t.ZipCode).HasColumnName("ZipCode"); // Relationships HasRequired(t => t.City) .WithMany(t => t.Posts) .Map(map=>map.MapKey("CityId")); } }

Creé una clase para manipular esos objetos con métodos estáticos que obtienen o crean objetos y los devuelven a la persona que llama.

private static City GetCity(string cityName) { City city; using (var db = new DbContext()) { city = db.Cities.SingleOrDefault(c => c.Name == cityName); if (city == null) { city = new City(cityName); db.Cities.Add(city); db.SaveChanges(); } } return city; } private static Post GetPost(string zipCode, string cityName) { Post post; City city = GetCity(cityName); using (var db = new DbContext()) { post = db.Posts.SingleOrDefault(p => p.City.Id == city.Id && p.ZipCode == zipCode); if (post == null) { post = new Post { City = city, ZipCode = zipCode }; // State of city is unchanged db.Posts.Add(post); // State of city is Added db.SaveChanges(); } } return post; }

Imagina, que llamo método

GetPost("11000","Prague");

El método GetCity se inicia y, si no existe, el método crea una city y luego llama al método SaveChanges() .

Si configuro la entidad de city devuelta en una nueva instancia de Post , Entity Framework genera una segunda inserción para la misma city .

¿Cómo puedo evitar este comportamiento? Solo quiero insertar una nueva entidad de post con una city referenciada creada o cargada en el paso anterior.


Debes establecer el State de tu ciudad cuando lo adjuntes sin cambios

context.Entry(city).State = EntityState.Unchanged;