2017-02-10 4 views
0

Я проверил по крайней мере 20 разных мест о том, как удалить реестр «много-ко-многим» с помощью Entity Framework, и мой код, похоже, работает по почти всем решения, которые я нашел. К сожалению, я не могу удалить отношения, несмотря ни на что. Вот код:EF Удаление многих из многих не работает должным образом

using (var db = new Context()) 
{     
    var project = db.Projects.Single(p => p.Id == "myId"); 

    foreach (var toRemove in project.Orders.Where(o => 
            ordersToRemove.Select(otr => otr.Id).Contains(o.Id)).ToList()) 
    { 
     project.Orders.Remove(toRemove); 

    } 
    db.SaveChanges(); 
} 

Я также попытался заставить удаление внутри «Еогеасп», получая заказ от «DB» и удаление отношения проекта из него, просто чтобы проверить, но это было бесполезно.

В качестве информации я отлаживал ее, и в моей коллекции заказов в проекте у Орденов были удалены правильно прямо перед «SaveChanges».

В том же коде у меня очень похожий поток, чтобы добавлять заказы в Project, и он отлично работает.

Я сделал отображение в контексте вручную, например:

modelBuilder.Entity<Project>() 
      .HasMany(p => p.Orders) 
      .WithMany(o => o.Projects) 
      .Map(pc => 
      { 
       pc.MapLeftKey("ProjectId"); 
       pc.MapRightKey("OrderId"); 
       pc.ToTable("Projects_Orders"); 
      }); 

Я считаю, что это что-то глупо, что я не могу понять, так что из-за этого я прошу вашей помощи. Извините, если это дублированный вопрос, но, как я уже говорил, я нашел много ответов, что код такой же, как у меня.

ОБНОВЛЕНО: Я узнал кого-то, у кого была такая же проблема, как и я (here), и я попытался использовать отмеченное решение, но не работал. Я также попытался очистить всю коллекцию, затем сохранить, а затем снова добавить заказы, которые должны остаться, и не работал. Другое решение заключалось в создании объекта для связанной таблицы (что-то вроде ProjectOrder), но я думал, что это будет слишком чертовски уродливо.

В конце концов, я использовал «executesqlcommand» - , и я не горжусь этим. К сожалению, я просто не мог потратить на это больше времени.

+0

Почему нет (!) В подзаголовке ordersToRemove? и что такое заказы? –

+0

Mistyped, извините. Уже исправлено. ordersToRemove - это список объект. В качестве информации я отлаживал ее, и в моей коллекции заказов в проекте были исправлены ордеры прямо перед «SaveChanges». – thiagoprzy

+0

Вы получаете какое-либо конкретное исключение? – Vinod

ответ

0

ОБНОВЛЕНО: Предыдущий ответ был отражением того, как удалить One-Many, вот обновленный образец, который я пробовал, и я могу удалить отношения Many-to-Many без каких-либо проблем. Пожалуйста, проигнорируйте соглашение об именах, так как я собрал это вместе для быстрого тестирования.

ORDER Entity

namespace TestEF6.Data 
{ 
    using System.Collections.Generic; 
    using System.ComponentModel.DataAnnotations; 
    using System.ComponentModel.DataAnnotations.Schema; 

    [Table("ORDER")] 
    public partial class ORDER 
    { 
     public ORDER() 
     { 
      PROJECTS = new HashSet<PROJECT>(); 
     } 

     [Key] 
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
     public int ID { get; set; } 

     [StringLength(50)] 
     public string NAME { get; set; } 

     public virtual ICollection<PROJECT> PROJECTS { get; set; } 
    } 
} 

предприятие ПРОЕКТ

namespace TestEF6.Data 
{ 
    using System.Collections.Generic; 
    using System.ComponentModel.DataAnnotations; 
    using System.ComponentModel.DataAnnotations.Schema; 

    [Table("PROJECT")] 
    public partial class PROJECT 
    { 
     public PROJECT() 
     { 
      ORDERS = new HashSet<ORDER>(); 
     } 

     [Key] 
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
     public int ID { get; set; } 

     [StringLength(50)] 
     public string NAME { get; set; } 

     public virtual ICollection<ORDER> ORDERS { get; set; } 
    } 
} 

Контекст класс

namespace TestEF6.Data 
{ 
    using System; 
    using System.Data.Entity; 

    public partial class ProjectManagerContext : DbContext 
    { 
     public ProjectManagerContext() 
      : base("name=ProjectManager") 
     { 
     } 

     public virtual DbSet<ORDER> ORDERs { get; set; } 
     public virtual DbSet<PROJECT> PROJECTs { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      Database.Log = Console.WriteLine; 

      modelBuilder.Entity<PROJECT>() 
      .HasMany(p => p.ORDERS) 
      .WithMany(o => o.PROJECTS) 
      .Map(pc => 
      { 
       pc.MapLeftKey("PROJECT_ID"); 
       pc.MapRightKey("ORDER_ID"); 
       pc.ToTable("PROJECT_ORDER"); 
      }); 
     } 
    } 
} 

БЛОК ТЕСТЫ

using System.Diagnostics; 
using System.Linq; 
using NUnit.Framework; 

namespace TestEF6.Data.Tests 
{ 
    [TestFixture] 
    public class ProjectOrderTests 
    { 
     [Test] 
     public void Can_Remove_Projects_And_Orders_Relation() 
     { 
      using (var db = new ProjectManagerContext()) 
      { 
       var proj1 = db.PROJECTs.Single(p => p.NAME == "TEST PROJ 1"); 

       Debug.WriteLine($"Num of proj1 orders = [{proj1.ORDERS.Count}]"); 
       foreach (var order in proj1.ORDERS.ToList()) 
       { 
        Debug.WriteLine($"Removed proj order = [{proj1.NAME}] [{order.NAME}]"); 
        proj1.ORDERS.Remove(order); 

       } 

       db.SaveChanges(); 
      } 
     } 

     [Test] 
     public void Can_Add_Projects_And_Orders() 
     { 
      using (var db = new ProjectManagerContext()) 
      { 
       var proj1 = new PROJECT { NAME = "TEST PROJ 1" }; 
       var proj2 = new PROJECT { NAME = "TEST PROJ 2" }; 
       var proj3 = new PROJECT { NAME = "TEST PROJ 3" }; 
       db.PROJECTs.Add(proj1); 
       db.PROJECTs.Add(proj2); 
       db.PROJECTs.Add(proj3); 
       db.SaveChanges(); 

       var order1 = new ORDER { NAME = "ORDER 1" }; 
       var order2 = new ORDER { NAME = "ORDER 2" }; 

       db.ORDERs.Add(order1); 
       db.ORDERs.Add(order2); 
       db.SaveChanges(); 

       proj1.ORDERS.Add(order1); 
       proj1.ORDERS.Add(order2); 
       proj2.ORDERS.Add(order2); 

       db.SaveChanges(); 
      } 
     } 


    } 
} 

Вот конфигурационный файл

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </configSections> 
    <entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
     <parameters> 
     <parameter value="mssqllocaldb" /> 
     </parameters> 
    </defaultConnectionFactory> 
    <providers> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
    </entityFramework> 
    <connectionStrings> 
    <add name="ProjectManager" connectionString="data source=MYTESTSQL2014;initial catalog=ProjectManagerDb;user id=test_user;password=test$pwd!;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" /> 
    </connectionStrings> 
</configuration> 

Вот как структура таблицы в сервере SQL определяется и соединения таблиц столбцы внешних ключей устанавливаются Разрешить аннулирует.

Project Order Relationship diagram

Результаты испытаний

enter image description here

Были 3 строки в таблице PROJECT_ORDER перед удалением

enter image description here

Существует только одна строка после удаления

enter image description here

+0

Здравствуйте, Vinod. Это решение разрешает только отношения «один ко многим», как говорит название URL. Моя проблема связана со многими отношениями. Другими словами, я не хочу удалять заказ, потому что он может быть связан с другим проектом. Я хочу удалить отношения между проектом и заказом. – thiagoprzy

+0

Извините, я раньше неправильно понял ваш вопрос. То, что у вас есть, должно работать. У меня есть аналогичный вариант использования, и он отлично работает. Насколько вы уверены в том, что выполнение достигает проекта. Orders.Remove (toRemove); линия? – Vinod

+0

Спасибо за обновленный ответ. О вашем вопросе: 100% уверен, поскольку я отлаживал его, а в моей коллекции Orders внутри проекта были правильно удалены Заказы прямо перед «SaveChanges». Мой код совсем не отличается от вашего, включая «null» в столбцах таблицы, так что это действительно mistery, почему он не работает. Больше информации в «обновленной» сессии в моем сообщении. – thiagoprzy

Смежные вопросы