4

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

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();

  }
}
4

3 回答 3

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);

        }
    }
于 2011-03-29T15:41:37.090 回答
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);

    }
}
于 2011-03-29T12:13:55.097 回答
1

这是另一个无法删除相关实体的情况。这就是错误:*来自“Order_Lines”关联集的关系处于“已删除”状态。给定多重约束,相应的“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);

        }
    }
于 2011-03-29T16:41:49.083 回答