EF Code First映射集合

4

我正在使用EF 4.1 RC Code First。在Junction表Friends中,我有一个使用复合PK的多对多关系。我们需要明确一个单独的Friends类(不要问为什么),该类表示我们的Junction表。我们的目标是能够从User实体控制删除过程。在阅读其余内容之前,请阅读此内容: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();

  }
}
3个回答

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

    }
}

再次问候Ladislav。我们今天早些时候尝试过这个,但出现了错误:指定的模式无效。错误: (23,6):错误0040:在命名空间Blogtronix.Repository(别名=Self)中未定义类型Friends_User1。请参考我们之前的对话:https://dev59.com/BVXTa4cB1Zd3GeqP13Zm#5392138 - mynkow
好的,我得自己试试,但我不能在工作时做这件事。 - Ladislav Mrnka
修改了我的回答。顺便说一下,你最后的错误只是说明你正在保存与不存在的用户的关系。 - Ladislav Mrnka
是的,这是我们做的第一个映射。正如你所说,它完美地工作了。然后我们尝试从集合中删除一个项目并保存用户对象。这个操作应该会从连接表中删除记录。但是没有成功 :( 这个问题的主要目的与页面顶部提供的链接有关。 - mynkow
相关文章不是关于映射的。它是关于普通关联和识别关联之间的区别(即场景1和场景2之间的区别)。如果您正好使用此映射并关闭级联删除,那么从集合中删除项目将不会将其删除。 - Ladislav Mrnka
显示剩余5条评论

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 中的关系处于“Deleted”状态。根据多重性约束,相应的“Order_Lines_Target”也必须处于“Deleted”状态。*

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

        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接