Question

I have a problem in EF 6 Code First while I am doing many to many relationship approaches. It will not populate my Tags and Posts list.

What I am trying to do:

Post

public class Post
{
    public int PostID { get; set; }

    public string Title { get; set; }
    public string Description { get; set; }

    public virtual Category Category { get; set; }
    public int CategoryID { get; set; }

    public virtual ICollection<Tag> Tags { get; set; }
}

Category

public class Category
{
    public int CategoryID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

Tag

public class Tag
{
    public int TagID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

PostTagMap

public class PostTagMap
{
    public virtual Post Post { get; set; }
    [Key, Column(Order = 0)]
    public int PostID { get; set; }

    public virtual Tag Tag { get; set; }
    [Key, Column(Order = 1)]
    public int TagID { get; set; }
}

PostDbContext

public class PostDbContext : DbContext
{
    public PostDbContext()
    {
        Database.SetInitializer(new PostDbContextInitializer());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Post> Post { get; set; }
    public DbSet<Tag> Tag { get; set; }
    public DbSet<Category> Category { get; set; }

    public DbSet<PostTagMap> PostTagMap { get; set; }
}

PostDbContextInitializer

public class PostDbContextInitializer : DropCreateDatabaseIfModelChanges<PostDbContext>
{
    protected override void Seed(PostDbContext context)
    {
        List<Category> listCategory = new List<Category>
        {
            new Category { Name = "Programming" },
            new Category { Name = "Designing" },
            new Category { Name = "Database" },
        };

        List<Tag> listTag = new List<Tag>
        {
            new Tag { Name = "Csharp" },
            new Tag { Name = "Asp.Net" },
            new Tag { Name = "Sencha Touch" },
            new Tag { Name = "MVC" },
            new Tag { Name = "SqlServer" },
            new Tag { Name = "Oracle" },
            new Tag { Name = "Bootstrap" },
            new Tag { Name = "Jquery" },
        };

        List<Post> listPost = new List<Post>
        {
            new Post { Title = "List Paging in Sencha Touch", Description = "In this one I am going to add one more important and most used functionality i.e. paging in sencha touch List.", Category = listCategory.Find(m => m.Name.Equals("Programming")) },
            new Post { Title = "CRUD Operation using Sencha Touch and ASP.Net MVC Web API", Description = "CRUD Operation using Sencha Touch and ASP.Net MVC Web API In this article I am going to explain and demonstrate how to create", Category = listCategory.Find(m => m.Name.Equals("Programming")) },
            new Post { Title = "Union Example in SQL Server", Description = "In this article I am going to explain a use of union operator in SQL Server Database with a real life scenario and example. The UNION operator is used to combine the result-set of two or more SELECT statements.", Category = listCategory.Find(m => m.Name.Equals("Database")) },
            new Post { Title = "Pivot with Dynamic columns in SQL Server", Description = "Pivot with Dynamic columns in SQL Server In this article I will present how we can write a Dynamic PIVOT.", Category = listCategory.Find(m => m.Name.Equals("Database")) },
        };

        List<PostTagMap> listPostTagMap = new List<PostTagMap>
        {
            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("List Paging in Sencha Touch")), Tag = listTag.Find(m => m.Name.Equals("Sencha Touch")) },
            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("List Paging in Sencha Touch")), Tag = listTag.Find(m => m.Name.Equals("Asp.Net")) },

            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("CRUD Operation using Sencha Touch and ASP.Net MVC Web API")), Tag = listTag.Find(m => m.Name.Equals("Sencha Touch")) },
            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("CRUD Operation using Sencha Touch and ASP.Net MVC Web API")), Tag = listTag.Find(m => m.Name.Equals("Asp.Net")) },
            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("CRUD Operation using Sencha Touch and ASP.Net MVC Web API")), Tag = listTag.Find(m => m.Name.Equals("MVC")) },
            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("CRUD Operation using Sencha Touch and ASP.Net MVC Web API")), Tag = listTag.Find(m => m.Name.Equals("Csharp")) },

            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("Union Example in SQL Server")), Tag = listTag.Find(m => m.Name.Equals("SqlServer")) },
            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("Union Example in SQL Server")), Tag = listTag.Find(m => m.Name.Equals("Oracle")) },

            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("Pivot with Dynamic columns in SQL Server")), Tag = listTag.Find(m => m.Name.Equals("Oracle")) },
            new PostTagMap { Post = listPost.Find(m => m.Title.Equals("Pivot with Dynamic columns in SQL Server")), Tag = listTag.Find(m => m.Name.Equals("SqlServer")) },
        };

        listCategory.ForEach(m =>
        {
            context.Category.Add(m);
        });
        context.SaveChanges();

        listTag.ForEach(m =>
        {
            context.Tag.Add(m);
        });
        context.SaveChanges();

        listPost.ForEach(m =>
        {
            context.Post.Add(m);
        });
        context.SaveChanges();

        listPostTagMap.ForEach(m =>
        {
            context.PostTagMap.Add(m);
        });
        context.SaveChanges();

        base.Seed(context);
    }
}

The above everything is working fine and database entry would also be correct. But the problem is occurring when I am trying retrieving a result set in Controller. It will not populating Tags list in Post and Posts list in Tag.

public class HomeController : Controller
{
    PostDbContext db = new PostDbContext();

    public ActionResult Index()
    {
        //var posts = db.Post.ToList();

        var posts = db.Post.Include(m => m.Tags).ToList();
        var tags = db.Tag.ToList();
        var categories = db.Category.ToList();

        return View(posts);
    }
}

Please help me. How can I achieve this?

Était-ce utile?

La solution

You do not need to create PostTagMap table explicitly. Entity framework will create the join table for you and as you are using Navigation properties (ICollection, etc.). Try addings a List of tags directly to one of your posts in the Seed method. This should then show up in your Index view.

Code:

public class Post
{
    public int PostID { get; set; }

    public string Title { get; set; }
    public string Description { get; set; }

    public virtual Category Category { get; set; }
    public int CategoryID { get; set; }

    public virtual ICollection<Tag> Tags { get; set; }
}

public class Category
{
    public int CategoryID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

public class Tag
{
    public int TagID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

public class PostDbContext : DbContext
{
    public PostDbContext()
    {
        Database.SetInitializer(new PostDbContextInitializer());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Post>().HasMany<Tag>(s => s.Tags).WithMany(c => c.Posts).Map(m =>
        {
            m.MapLeftKey("PostID");
            m.MapRightKey("TagID");
            m.ToTable("PostTagMap");
        });

        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Post> Post { get; set; }
    public DbSet<Tag> Tag { get; set; }
    public DbSet<Category> Category { get; set; }
}

public class PostDbContextInitializer : DropCreateDatabaseIfModelChanges<PostDbContext>
{
    protected override void Seed(PostDbContext context)
    {
        List<Category> listCategory = new List<Category>
        {
            new Category { Name = "Programming" },
            new Category { Name = "Designing" },
            new Category { Name = "Database" },
        };

        List<Tag> listTag = new List<Tag>
        {
            new Tag { Name = "Csharp" },
            new Tag { Name = "Asp.Net" },
            new Tag { Name = "Sencha Touch" },
            new Tag { Name = "MVC" },
            new Tag { Name = "SqlServer" },
            new Tag { Name = "Oracle" },
            new Tag { Name = "Bootstrap" },
            new Tag { Name = "Jquery" },
        };

        List<Post> listPost = new List<Post>
        {
            new Post { Title = "List Paging in Sencha Touch", Description = "In this one I am going to add one more important and most used functionality i.e. paging in sencha touch List.", Category = listCategory.Find(m => m.Name.Equals("Programming")), Tags = listTag.Where(x => x.Name.Equals("Sencha Touch") || x.Name.Equals("Asp.Net")).ToList() },
            new Post { Title = "CRUD Operation using Sencha Touch and ASP.Net MVC Web API", Description = "CRUD Operation using Sencha Touch and ASP.Net MVC Web API In this article I am going to explain and demonstrate how to create", Category = listCategory.Find(m => m.Name.Equals("Programming")) },
            new Post { Title = "Union Example in SQL Server", Description = "In this article I am going to explain a use of union operator in SQL Server Database with a real life scenario and example. The UNION operator is used to combine the result-set of two or more SELECT statements.", Category = listCategory.Find(m => m.Name.Equals("Database")) },
            new Post { Title = "Pivot with Dynamic columns in SQL Server", Description = "Pivot with Dynamic columns in SQL Server In this article I will present how we can write a Dynamic PIVOT.", Category = listCategory.Find(m => m.Name.Equals("Database")) },
        };

        listCategory.ForEach(m =>
        {
            context.Category.Add(m);
        });
        context.SaveChanges();

        listTag.ForEach(m =>
        {
            context.Tag.Add(m);
        });
        context.SaveChanges();

        listPost.ForEach(m =>
        {
            context.Post.Add(m);
        });
        context.SaveChanges();

        base.Seed(context);
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top