实体框架4 CTP 5 POCO - 多对多配置,插入和更新?

时间:2011-02-11 23:15:45

标签: entity-framework entity-framework-4 many-to-many poco entity-relationship

我真的需要有人帮助我完全理解如何与Entity Framework 4 CTP 5,POCO建立多对多的关系。我需要理解3个概念:

  1. 如何配置我的模型来指示 有些表是多对多的。
  2. 如何正确插入。
  3. 如何正确更新。
  4. 以下是我目前的型号:

    public class MusicSheet
    {
        [Key]
        public int ID { get; set; }
        public string Title { get; set; }
        public string Key { get; set; }
    
        public virtual ICollection<Author> Authors { get; set; }
        public virtual ICollection<Tag> Tags { get; set; }
    }
    
    public class Author
    {
        [Key]
        public int ID { get; set; }
        public string Name { get; set; }
        public string Bio { get; set; }
    
        public virtual ICollection<MusicSheet> MusicSheets { get; set; }
    }
    
    public class Tag
    {
        [Key]
        public int ID { get; set; }
        public string TagName { get; set; }
    
        public virtual ICollection<MusicSheet> MusicSheets { get; set; }
    }
    

    正如您所看到的,MusicSheet可以有多个AuthorsTagsAuthorTag可以有多个MusicSheets

    同样,我的问题是:

    1. 该怎么做 EntityTypeConfiguration设置 他们之间的关系以及 映射到表/对象 与多对多联系 关系。
    2. 如何插入新的音乐表 (它可能有多个 作者或多个标签)。
    3. 如何更新音乐表。对于 例如,我可能会设置 TagA TagB 到MusicSheet1,但稍后我需要将代码更改为 TagA TagC 。好像我需要 首先检查是否有标签 已存在,如果没有,请插入 新标签,然后将其关联 音乐表(所以我没有 重新插入 TagA ?)。或者这是 已经处理过的东西 框架?
    4. 非常感谢你。我真的希望完全理解它而不仅仅是在没有完全理解正在发生的事情的情况下这样做。特别是#3。

2 个答案:

答案 0 :(得分:5)

  1. 在EF4 CTP5中,当您将公共虚拟ICollection放在多对多关系的每个类中时,默认约定完成关系,就像您已经完成的那样,您的上下文类应如下所示:< / p>

    public class YourContextName : DbContext
    {
        public DbSet<MusicSheet> MusicSheets { get; set; }
        public DbSet<Tag> Tags { get; set; }
        public DbSet<Author> Authors { get; set; }
    }
    
  2. 很简单,您只需创建一个MusicSheet类的实例,然后将作者和标签的所有实例添加到MusicSheet中的每个作者和标签集合中,然后将您的MusicSheet实例添加到您的MusicSheets的上下文集合,然后调用SaveChanges:

            MusicSheet musicSheet = new MusicSheet
                                    {
                                        Title = "Music Sheet 1",
                                        Key = "Key",
                                        Authors = new List<Author>
                                                      {
                                                          new Author
                                                              {
                                                                  Name = "Author 1",
                                                                  Bio = "Author 1 biographic text..."
                                                              },
                                                          new Author
                                                              {
                                                                  Name = "Author 2",
                                                                  Bio = "Author 2 biographic text..."
                                                              }
                                                      },
    
                                        Tags = new List<Tag>
                                                   {
                                                       new Tag {TagName = "TagA"},
                                                       new Tag {TagName = "TagC"}
                                                   }
                                    };
    
    
        var context = new YourContextName();
        context.MusicSheets.Add(musicSheet);
        context.SaveChanges();
    
  3. 要更新您必须加载您的MusicSheet并删除您不想要的标签,然后添加您需要添加的标签,具体方法如下:

        var context = new YourContextName();
        var myMusicSheet = context.MusicSheets.First();
    
        //The Tag you wnat to remove.
        var tagToRemove = myMusicSheet.Tags.First();
    
        var tagToAdd = new Tag {TagName = "TagX"};
    
        myMusicSheet.Tags.Remove(tagToRemove);
        myMusicSheet.Tags.Add(tagToAdd);
    
        context.Entry(myMusicSheet).State = EntityState.Modified;
        context.SaveChanges();
    
  4. 您还可以找到您知道存在并添加到MusicSheet的任何作者和/或标签,反之亦然,但这是基础。

    请记住这首先是针对EF4 CTP5代码......

    对不起,我的英语不是我的主要语言,我希望这可以帮助你,多米尼加共和国的问候。

    PS:不要忘记添加对EntityFramework和System.Data.Entity的引用,你有责任做其他事情,比如单元测试,验证,异常处理......等等。

    修改

    首先,您需要为模型添加构造函数:

    public class Tag
    {
        [Key]
        public int ID { get; set; }
        public string TagName { get; set; }
    
        public Tag()
        {
           MusicSheets = new List<MusicSheet>();
        }        
    
        public virtual ICollection<MusicSheet> MusicSheets { get; set; }
    }
    

    ...然后你可以这样做:

    var context = new YourContextName();
    var newMusicSheet = new MusicSheet();
        newMusicSheet.Title = "Newly added Music Sheet";
    
    //Your existing Tag.
    var existingTag = contex.Tags.Find(3);        
    
    existingTag.MusicSheets.Add(existingTag);
    
    context.Entry(existingTag).State = EntityState.Modified;
    context.SaveChanges();
    

    您可以为所有型号执行相同操作。

    我希望这可以帮到你!

答案 1 :(得分:0)

您实际上不需要EntityTypeConfiguration来设置它们之间的关系。它应该现在正常工作。使用CTP5,建立多对多关系所需要做的就是在两个实体中包含ICollection。

现在关于如何执行插入和删除,我知道有两种方法。我通常使用的是为多对多关系的结果表创建一个实体,然后创建该实体的实例并用所有必需的数据提供它,包括其他实体的实例(那些实体的实例)有多对多的关系)。最后,我只需将其添加到存储库并提交事务(通常使用UnitOfWork类)。

快速举例:

public class Item
{
    public int ID { get; set; }
    public string Title { get; set; }
    public virtual ICollection<Bid> Bids { get; set; }
}

public class User 
{
    public int ID { get; set; }
    public string Username{ get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public virtual ICollection<Bid> Bids { get; set; }
}

public class Bid
{
    public int ID { get; set; }
    public float Amount { get; set; }
    public DateTime Date { get; set; }
    public virtual Item Item { get; set; }
    public virtual User User { get; set; }
}

然后我只想创建Bid实体的实例。

public void PlaceBid(User user, Item item, int amount)
{
    if (ValidateBid(amount, user, item))
    {
        Bid bid = new Bid
        {
            Amount = amount,
            Date = DateTime.Now,
            User = user,
            Item = item
        };

        try
        {
            repository.Add(bid);
            unitOfWork.Commit();
        }
        catch (Exception ex)
        {
            //TODO: Log the exception
            throw;
        }
    }
}