2011-03-29 34 views
4

我首先使用EF 4.1 RC代码。我有一个多对多的关系,在交界处朋友中使用复合PK。我们明确需要一个单独的Friends类(不问),它代表了我们的联结表。我们的目标是能够控制用户实体的删除过程。在阅读其余部分之前,请阅读本文:http://mocella.blogspot.com/2010/01/entity-framework-v4-object-graph.html。所以,我们设法创建了我们的复合PK,但是这打破了我们的收藏映射。问题是如何映射FriendsCol?EF代码首次映射用于收集

public class User 
{ 
    public int UserId { get; set; } 
    public string Name { get; set; } 
    public virtual ICollecion<Friends> FriendsCol { get; set; } 

} 

public class Friends 
{ 
    public int User1Id { get; set; } 
    public int User2Id { get; set; } 

    public User User1 { get; set; } 
    public User User2 { get; set; } 

} 

具有复合键映射

public class FriendsMap : EntityTypeConfiguration<Friends> 
{ 
    HasKey(m => new { m.userId1 , m.userId2 }); 

    //this.HasRequired(x => x.User1) 
    //.WithMany() 
    //.HasForeignKey(x => x.User1Id) 
    //.WillCascadeOnDelete(false); 

    //this.HasRequired(x => x.User2) 
    // .WithMany() 
    // .HasForeignKey(x => x.User2Id) 
    // .WillCascadeOnDelete(false); 
} 

public class UserMap : EntityTypeConfiguration<UserNew> 
{ 
    public UserMap()    
    { 
    ToTable("users"); 
    Property(user => user.Name).HasColumnName("name"); 
    // HasMany<Friends>(user => user.FriendsCol).WithMany(); 

    } 
} 

回答

1

这个怎么样:

public class FriendsMap : EntityTypeConfiguration<Friends> 
{ 
    HasKey(m => new { m.userId1 , m.userId2 }); 

    this.HasRequired(x => x.User1) 
     .WithMany() 
     .HasForeignKey(x => x.User1Id) 
     .WillCascadeOnDelete(false); 

    this.HasRequired(x => x.User2) 
     .WithMany(u => u.FriendsCol) 
     .HasForeignKey(x => x.User2Id) 
     .WillCascadeOnDelete(false); 
} 

public class UserMap : EntityTypeConfiguration<UserNew> 
{ 
    public UserMap()    
    { 
    ToTable("users"); 
    Property(user => user.Name).HasColumnName("name"); 
    } 
} 

编辑:

我只是做了很简单的例子,它的作品没有任何问题:

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var context = new Context()) 
     { 
      context.Database.Delete(); 
      context.Database.CreateIfNotExists(); 

      var u1 = new User() { Name = "A" }; 
      var u2 = new User() { Name = "B" }; 
      var u3 = new User() { Name = "C" }; 

      var f1 = new Friends() { User1 = u1, User2 = u2}; 
      var f2 = new Friends() { User1 = u1, User2 = u3 }; 

      context.Friends.Add(f1); 
      context.Friends.Add(f2); 
      context.SaveChanges(); 
     } 
    } 
} 

public class User 
{ 
    public int UserId { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Friends> FriendsCol { get; set; } 
} 

public class Friends 
{ 
    public int User1Id { get; set; } 
    public int User2Id { get; set; } 

    public User User1 { get; set; } 
    public User User2 { get; set; } 

} 

public class Context : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
    public DbSet<Friends> Friends { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Friends>() 
      .HasKey(m => new { m.User1Id, m.User2Id }); 

     modelBuilder.Entity<Friends>() 
      .HasRequired(x => x.User1) 
      .WithMany() 
      .HasForeignKey(x => x.User1Id) 
      .WillCascadeOnDelete(false); 

     modelBuilder.Entity<Friends>() 
      .HasRequired(x => x.User2) 
      .WithMany(u => u.FriendsCol) 
      .HasForeignKey(x => x.User2Id) 
      .WillCascadeOnDelete(false); 

    } 
} 
+0

嗨拉迪斯拉夫。我们今天早些时候尝试过,错误是:指定的Schema无效。错误: (23,6):错误0040:类型Friends_User1未在名称空间Blogtronix.Repository(Alias = Self)中定义。考虑我们的prev对话:http://stackoverflow.com/questions/5391679/ef-cf-many-to-many-relation-with-additional-info/5392138#5392138 – mynkow 2011-03-29 12:21:34

+0

再试一次,我编辑了我的答案。 – 2011-03-29 12:31:50

+0

我们也试过这个。然后我们得到FK错误:{“INSERT语句与FOREIGN KEY约束\”Friends_User1 \“冲突。数据库\”CoreContext \“,表\”dbo.users \“,列'user_id'发生冲突。\ r \ n声明已被终止。“} PS:user_id是用户PK。 – mynkow 2011-03-29 12:36:58

1

好了,这里真的会发生什么:

class Program 
    { 
     static void Main(string[] args) 
     { 
      int id1; 
      int id2; 
      using (var context = new Context()) 
      { 
       context.Database.Delete(); 
       context.Database.CreateIfNotExists(); 

       var u1 = new User() { Name = "A" }; 
       var u2 = new User() { Name = "B" }; 
       var u3 = new User() { Name = "C" }; 

       var f1 = new Friends() { User1 = u1, User2 = u2 }; 
       var f2 = new Friends() { User1 = u1, User2 = u3 }; 

       u1.FriendsCol.Add(f1); 
       u1.FriendsCol.Add(f2); 
       context.SaveChanges(); 

       id1 = u1.Id; 
       id2 = u2.Id; 
      } 

      using (var context = new Context()) 
      { 
       var u1 = context.Users.Find(id1); 

       var friendsToRemove = u1.FriendsCol.Where(f => f.User2.Id == id2).ToList(); 
       foreach (var friend in friendsToRemove) 
       { 
        u1.FriendsCol.Remove(friend); 
       } 

       context.SaveChanges(); 
      } 
     } 
    } 

    public class User 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public virtual ICollection<Friends> FriendsCol { get; set; } 

     public User() 
     { 
      FriendsCol = new List<Friends>(); 
     } 
    } 

    public class Friends 
    { 
     public int User1Id { get; set; } 
     public int User2Id { get; set; } 

     public User User1 { get; set; } 
     public User User2 { get; set; } 

    } 

    public class Context : DbContext 
    { 
     public DbSet<User> Users { get; set; } 
     public DbSet<Friends> Friends { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      base.OnModelCreating(modelBuilder); 

      modelBuilder.Entity<Friends>() 
       .HasKey(m => new { m.User1Id, m.User2Id }); 

      modelBuilder.Entity<Friends>() 
       .HasRequired(x => x.User1) 
       .WithMany() 
       .HasForeignKey(x => x.User1Id); 

      modelBuilder.Entity<Friends>() 
       .HasRequired(x => x.User2) 
       .WithMany(u => u.FriendsCol) 
       .HasForeignKey(x => x.User2Id); 

     } 
    } 
1

这里是另一个无法删除相关的实体。这是错误:*来自'Order_Lines'AssociationSet的关系处于'已删除'状态。给定多重约束,相应的'Order_Lines_Target'也必须处于'已删除'状态。*

class Program 
    { 
     static void Main(string[] args) 
     { 
      int orderid1; 
      int Lineid2; 
      using (var context = new Context()) 
      { 
       var u1 = new Order() { Name = "A" }; 
       var l1 = new OrderLine() { Name = "L1" }; 
       var l2 = new OrderLine() { Name = "L2" }; 

       u1.Lines.Add(l1); 
       u1.Lines.Add(l2); 
       context.Orders.Add(u1); 
       context.SaveChanges(); 

       Orderid1 = u1.Id; 
       Lineid2 = l2.Id; 
      } 

      using (var context = new Context()) 
      { 
       var u1 = context.Orders.Find(Orderid1); 
       foreach (var item in u1.Lines) 
       { 
        if (item.Id == Lineid2) 
        { 
         u1.Lines.Remove(item); 
         break; 
        } 
       } 

       context.SaveChanges(); 
      } 
     } 
    } 

    public class OrderLine 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public Order Order { get; set; } 
    } 

    public class Order 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public virtual ICollection<OrderLine> Lines { get; set; } 

     public Order() 
     { 
      Lines = new List<OrderLine>(); 
     } 
    } 

    public class Context : DbContext 
    { 
     public DbSet<Order> Orders { get; set; } 
     public DbSet<OrderLine> OrderLiness { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Entity<Order>().HasMany<OrderLine>(o => o.Lines).WithRequired(l => l.Order); 

     } 
    }