jtb5017
jtb5017

Reputation: 11

Entity Framework and Data binding

I have two tables that are built using codefirst entity framework.

public class TimeEntry:Entity
{
    [Required]
    [Display(Name = "Activity")]
    public int ActivityId { get; set; }

    public virtual Activity Activity { get; set; }  
}

public class Activity:Entity
{
    private ICollection<TimeEntry> _timeEntries;


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

    public virtual ICollection<TimeEntry> TimeEntries
    {
        get
        {
            return _timeEntries ?? (_timeEntries = new List<TimeEntry>());
        }
        set
        {
            _timeEntries = value;
        }
    }
}
public class Entity
{
    public int Id { get; set; }
}

These are the classes I have created for my Db. There is no problem with creating the database. When I try to perform CRUD operations I get the error

DataBinding: 'System.Data.Entity.DynamicProxies.Activity_AD12BF558F098271F1F51B3B1489B4B3B281FD0B686C8457333DE5BEE0E8B6A9' does not contain a property with the name 'ActivityId'

It is trying to find ActivityId in the Activity table however the primary key is Id. How do I map the foreign key ActivityId in the TimeEntry table to the primary key Id in the Activity table.

Upvotes: 1

Views: 5137

Answers (3)

Fadi
Fadi

Reputation: 2370

hi i have the same problem

  1. If one specifies DataKeyNames property as ID and the actual column name is CustomerID. It will throw the above error.

  2. If one specifies DataTextField or DataValueField property as ID and the actual column name is CustomerID. It will throw the above error.

and found the answer here it work for me link

Upvotes: 1

StuartLC
StuartLC

Reputation: 107327

If you are using Code First, you need to indicate the mapping of ActivityId => Id by overriding OnModelCreating in your DbContext.

At a suggestion, it seems you are mixing the concerns of DTO and MVC ViewModel in the same entity. Why not separate these concerns into 2 different entities?

Upvotes: 0

Kamyar
Kamyar

Reputation: 18797

You can use fluent api to let EF know about you mappings.

public class ActivityMap : EntityTypeConfiguration<Activity>
{
    public ActivityMap()
    {
         this.HasKey(a => a.Id);
    }
}

public class TimeEntryMap : EntityTypeConfiguration<TimeEntry>
{
    public TimeEntryMap()
    {
        this.HasKey(t => t.Id);
        // Relationships
        this.HasRequired(t => t.Activity)
            .WithMany(t => t.TimeEntries)
    }            .HasForeignKey(d => d.ActivityId);
}  

Then in your context:

public class MyDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new ActivityMap());
        modelBuilder.Configurations.Add(new TimeEntryMap());
    }
}  

I think this will solve your issue.

Also, (as a side note) instead of defining _timeEntries, you can use auto implemented property for TimeEntries and initialize it in you ctor. like below:

public class Activity:Entity
{
    public virtual ICollection<TimeEntry> TimeEntries { get; set; }
    public Activity()
    {
        this.TimeEntries = new List<TimeEntry>();
    }
}

Upvotes: 3

Related Questions