简体   繁体   English

实体框架4.1代码创建多对多关系的第一种方法

[英]Entity Framework 4.1 Code First approach to create many-to-many relation

I'm using the Silverlight 5 Beta SDK and the EntityFramework 4.1 in an Silverlight Application. 我在Silverlight应用程序中使用Silverlight 5 Beta SDK和EntityFramework 4.1。

I'll try to create the two tables 'Author' and 'Book'. 我将尝试创建两个表'Author'和'Book'。 In SQL, there should be a third (join) table, which makes the many-to-many relation between Author and Book (one author could have written many books and a book could be written from many authors). 在SQL中,应该有第三个(连接)表,它在Author和Book之间建立多对多关系(一个作者可以编写很多书,一本书可以从许多作者那里编写)。

This is what I've got so far: 这是我到目前为止所得到的:

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

The most obvious problem is, that the navigation properties (Books in Author and Authors in Book) aren't created from the code designer in my client project. 最明显的问题是,导航属性(Book中的Books和Book中的作者)不是从我的客户端项目中的代码设计器创建的。

What do I need to do? 我需要做什么?

EDIT: Okay, now I'm able to use only one of the NavigationProperties simultaneously. 编辑:好的,现在我只能同时使用其中一个NavigationProperties。 If I try to 'Include' both I'm getting the following error: 如果我试图'包含',我会收到以下错误:

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.

This is my updated code: 这是我更新的代码:

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

It seems to me, that Entity Framework still isn't able to deal with many-to-many relations. 在我看来,实体框架仍然无法处理多对多关系。 At least, that's what the error message implies. 至少,这就是错误信息所暗示的。

EDIT2: I've changed my code after I've read this post on social.msdn : 编辑2:在我阅读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; }
}

It doesn't fixed my problem. 它没有解决我的问题。 The same error is still present. 仍然存在相同的错误。 I've tested to remove the AssociationAttribute without success. 我已经测试过删除AssociationAttribute但没有成功。 Am I doing somethinf wrong here? 我在这里做错了吗?

I think problem here lies in the WCF RIA service, not anything EF related. 我认为这里的问题在于WCF RIA服务,而不是EF相关的任何问题。 That is, that WCF doesn't like interfaces. 也就是说,WCF不喜欢接口。 Solution would be use Collection instead of ICollection . 解决方案是使用Collection而不是ICollection I'm sure EF won't mind it and it will fix your WCF problem. 我确信EF不会介意它,它会解决你的WCF问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Entity Framework 4.1 - Code First:多对多关系 - Entity Framework 4.1 - Code First: many-to-many relationship 通过具有多对多关系的实体框架代码优先方法为 SQL Server 播种 - Seeding SQL Server by Entity Framework code-first approach with many-to-many relationship 在Entity Framework 6中更新多对多关系的问题(代码优先) - Problems with updating many-to-many relationships in Entity Framework 6 (Code First) 在Entity Framework 6.1中添加列 - 多对多 - 代码优先 - Adding column in Entity Framework 6.1 - Many-To-Many - Code First 代码优先实体框架-多对多关系 - Code-first Entity Framework - many-to-many relationships 实体框架代码优先的多对多关系 - Entity framework code first many-to-many relationshiop initialization 实体框架代码第一个多对多保存问题 - Entity framework code first many-to-many saving issue 编写第一个实体框架(EF6)的代码,在初始创建后添加多对多关系 - Code first Entity Framework (EF6) Adding Many-to-Many relationship after initial create 如何首先使用Entity Framework代码创建多对多关系? - How do I create a many-to-many relationship with Entity Framework code first? 实体框架代码首先不创建多对多数据库表 - Entity framework code first does not create many-to-many database table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM