【问题标题】:Entity Framework 4.1 Code First approach to create many-to-many relationEntity Framework 4.1 Code First 方法来创建多对多关系
【发布时间】:2011-05-09 12:25:55
【问题描述】:

我在 Silverlight 应用程序中使用 Silverlight 5 Beta SDK 和 EntityFramework 4.1。

我将尝试创建两个表“Author”和“Book”。在 SQL 中,应该有第三个(连接)表,它在 Author 和 Book 之间建立了多对多的关系(一个作者可能写过很多书,而一本书可能是由多个作者写的)。

这是我目前得到的:

namespace CodeFirst.Models.Web
{    
    public class Author
    {
        public Author()
        {
            this.Books = new HashSet<Book>();
        }

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

        [Required]
        public string Name { get; set; }

        public ICollection<Book> Books { get; set; }
    }


    public class Book
    {
        public Book()
        {
            this.Authors = new HashSet<Author>();
        }


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

        [Required]
        public string Name { get; set; }

        public ICollection<Author> Authors { get; set; }
    }


    // Should I do something like that:
    public class AuthorMapping : EntityTypeConfiguration<Author>
    {
        public AuthorMapping() : base()
        {   
            //this.HasMany (g => g.Books)
            //    .WithMany(m => m.Authors)
            //    .Map     (gm => gm.ToTable    ("Author_Book")
            //                      .MapLeftKey ("AuthorID")
            //                      .MapRightKey("BookID"));
        }
    }


    public class CodeFirstModelContext : DbContext
    {
        public CodeFirstModelContext() : base()
        {
            this.Database.Connection.ConnectionString = @".\MSSQLSERVER2008;Database=CodeFirst;Trusted_Connection=true;";
        }


        public DbSet<Author> Authors  { get; set; }
        public DbSet<Book>   Books { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new AuthorMapping());

            // tell Code First to ignore PluralizingTableName convention
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }


    [EnableClientAccess()]
    public class CodeFirstDomainService : DomainService
    {
        public CodeFirstDomainService()
        {
            this.m_modelContext = new CodeFirstModelContext();
        }


        public IQueryable<Author> GetAuthors()
        {
            return this.m_modelContext.Authors;//.Include("Books");
        }

        public void InsertAuthor(Author Author)
        {
            this.m_modelContext.Insert(Author);
        }

        public void UpdateAuthor(Author Author)
        {
            this.m_modelContext.Update(Author, this.ChangeSet.GetOriginal(Author));
        }

        public void DeleteAuthor(Author Author)
        {
            this.m_modelContext.Delete(Author);
        }


        public IQueryable<Book> GetBooks()
        {
            return this.m_modelContext.Books;//.Include("Authors");
        }

        public void InsertBook(Book Author)
        {
            this.m_modelContext.Insert(Author);
        }

        public void UpdateBook(Book Author)
        {
            this.m_modelContext.Update(Author, this.ChangeSet.GetOriginal(Author));
        }

        public void DeleteBook(Book Author)
        {
            this.m_modelContext.Delete(Author);
        }


        protected override void Dispose(bool disposing)
        {
            if (disposing)
                this.m_modelContext.Dispose();
            base.Dispose(disposing);
        }

        protected override bool PersistChangeSet()
        {
            this.m_modelContext.SaveChanges();
            return base.PersistChangeSet();
        }


        private CodeFirstModelContext m_modelContext;
    }
}

最明显的问题是,导航属性(Books in Author 和 Authors in Book)不是从我的客户端项目中的代码设计器创建的。

我需要做什么?

编辑: 好的,现在我只能同时使用其中一个 NavigationProperties。如果我尝试“包含”两者,我会收到以下错误:

Association 'Author_Book' defined on entity type 'CodeFirst.Models.Web.Author' is invalid. It is a foreign key association but the property type is not a singleton.

这是我更新的代码:

public class Author
{
    public Author()
    {
        this.Books = new Collection<Book>();
    }

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

    [MaxLength(32)]
    [Required]
    public string Name { get; set; }

    [Association("Author_Book", "ID", "ID")]
    [Include]
    public Collection<Book> Books { get; set; }
}


public class Book
{
    public Book()
    {
        this.Authors = new Collection<Author>();
    }

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

    [MaxLength(32)]
    [Required]
    public string Name { get; set; }

    [Association("Author_Book", "ID", "ID")]
    [Include]
    public Collection<Author> Authors { get; set; }
}


public class AuthorMapping : EntityTypeConfiguration<Author>
{
    public AuthorMapping() : base()
    {
        this.HasMany (g => g.Books)
            .WithMany(m => m.Authors)
            .Map     (gm => gm.ToTable("Author_Book"));
    }
}

public class BookMapping : EntityTypeConfiguration<Book>
{
    public BookMapping() : base()
    {
        this.HasMany (m => m.Authors)
            .WithMany(g => g.Books)
            .Map     (gm => gm.ToTable("Author_Book"));
    }
}

在我看来,Entity Framework 仍然无法处理多对多关系。至少,这就是错误消息所暗示的内容。

EDIT2: 我在阅读this post on social.msdn 后更改了我的代码:

public class Author
{
    public Author()
    {
        this.Books = new Collection<Book>();
    }

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

    [MaxLength(32)]
    [Required]
    public string Name { get; set; }

    [Association("Author_Book", "Book_ID", "Author_ID")]
    [Include]
    [ForeignKey("Book_ID")]
    public Collection<Book> Books { get; set; }
    public int Book_ID { get; set; }
}

public class Book
{
    public Book()
    {
        this.Authors = new Collection<Author>();
    }

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

    [MaxLength(32)]
    [Required]
    public string Name { get; set; }

    [Association("Author_Book", "Author_ID", "Book_ID")]
    [Include]
    [ForeignKey("Author_ID")]
    public Collection<Author> Authors { get; set; }
    public int Author_ID { get; set; }
}

它没有解决我的问题。同样的错误仍然存​​在。我已经测试过删除 AssociationAttribute 没有成功。我在这里做错了吗?

【问题讨论】:

  • @Caglar Gonul:感谢您的回答,但我看不出这与我的问题有何关联。我没有扩展或映射现有的数据库或表。我正在使用“代码优先”从实体框架的代码创建表。
  • >我的客户项目中的代码设计器。什么?你在使用 WCF 吗?您能向我们展示由此生成的表格吗?

标签: c# silverlight many-to-many entity-framework-4.1 code-first


【解决方案1】:

我认为这里的问题在于 WCF RIA 服务,而不是任何与 EF 相关的东西。也就是说,WCF 不喜欢接口。解决方案是使用Collection 而不是ICollection。我相信 EF 不会介意它,它会解决你的 WCF 问题。

编辑:这可能会解决您的问题http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/d894c8af-5985-4995-88e2-c8733e4a51ea

【讨论】:

  • +1 |是的,它奏效了。不幸的是,这非常不清楚,几乎没有记录。非常感谢!
  • 好的,现在我遇到了另一个错误。我已经编辑了我的初始帖子。
  • 我认为你应该只用新问题打开新问题。
猜你喜欢
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-17
  • 2011-09-10
  • 1970-01-01
相关资源
最近更新 更多