0

I have multiple models (tasks/servers/etc.) and all of these models need to support comments. I would like to have a centralized comments table that all of these models can reference (I am open to other designs though).

The comments table will have the following fields:

CommentID
RefTable
RefId
Text

I can use the following code in the task class (for example) to reference the task's comments.

IEnumerable<Comment> comments = Comment.Find(this.GetType().Name, this.TaskID)

However, I would prefer to create a HasMany mapping from tasks to comments so that I can use the following code.

this.Comments

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.ModelConfiguration;

namespace Models.Mapping
{
    public class TaskMap : EntityTypeConfiguration<Task>
    {
        public TaskManagerItemMap()
        {
            // Primary Key
            this.HasKey(t => t.TaskID);

            ...

            this.Property(t => t.TaskID).HasColumnName("TaskID")

            ...

            this.ToTable("Task");

         }

    }
}

using System;
using System.Collections.Generic;

namespace Models
{
    public partial class Task
    {
        public int TaskID { get; set; }

        ....

        public virtual IEnumerable<Comment> Comments { get; set; }

        ...
    }
}

using System.ComponentModel.DataAnnotations;
using System.Data.Entity.ModelConfiguration;

namespace Models.Mapping
{
    public class CommentMap : EntityTypeConfiguration<Comment>
    {
        public CommentMap()
        {
            this.HasKey(t => new { t.RefID, t.RefTable });

            this.ToTable("Comment");
            this.Property(t => t.CommentID).HasColumnName("CommentID")
                .IsRequired();

            this.Property(t => t.RefID).HasColumnName("RefID")
                .IsRequired();

            this.Property(t => t.RefTable).HasColumnName("RefTable")
                .IsRequired();

            this.Property(t => t.Text).HasColumnName("Text")
                .IsRequired();
        }
    }
}

using System;
using System.Collections.Generic;

namespace Models
{
    public partial class Comment
    {
        public int CommentID { get; set; }
        public int RefID { get; set; }
        public string RefTable { get; set; }
        public string Text { get; set; }
    }
}

using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Globalization;
using Vocus50.SiteManager.SiteManager2014.Models.Mapping;

namespace Models
{
    public partial class DataContext : DbContext
    {
        static DataContext()
        {
            Database.SetInitializer<DataContext>(null);
        }

        public DataContext()
            : base("Name=DataContext")
        {
        }

        public DbSet<Task> Task{ get; set; }
        public DbSet<Comment> Comment { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new TaskMap());
            modelBuilder.Configurations.Add(new CommentMap());
        }
    }
}
gposton
  • 59
  • 7

2 Answers2

0

If you use the above code, it would seem to me the issue would be in sending over the RefTable (or RefModel from above - are those supposed to be the same?) One option here (there may be many others) would be to override SaveChanges and inspect the value (or fill in) upon save.

So if you override SaveChanges (a rough method below, there are many samples on the net) you would fill in this table based on the entity type. It feels hacky, so there is probably a better solution

Is there an easy way to make EntityFramework use SQL default values?

That is of course if I understood this correctly : )

Community
  • 1
  • 1
Adam Tuliper
  • 29,982
  • 4
  • 53
  • 71
  • RefTable and RefModel are the same. I updated the question to remove the confusion. You understood the question correctly, and your solution would work, but it does seem hacky. I'd prefer to create a standard mapping, but override the conventions used to define the map. For example, MVC assumes that there will be a 'CommentID' field for a standard mapping. I'd like to override this convention and give it a new way to 'lookup' the relationship. I have a Rails background, and in Rails you can accomplish this by using a [polymorphic association](https://join.me/551-141-283). – gposton Mar 04 '13 at 16:40
0

Have you looked into using Automapper. I believe you can use this for the functionality your looking for.

Robert
  • 4,306
  • 11
  • 45
  • 95