C# – Entity Framework: Adding object with foreign key

centity-frameworksql server

I have 2 tables Jobs and Schedule

Jobs

JobId – int,PK, Identity
ScheduleId – int, FK
Title – varchar
Description – varchar

Schedules

ScheduleId – int,PK, Identity
Name – varchar

There is a relationship one to many with cascade on delete.

When I create Entity model, the generated Jobs model removes the ScheduleId field.

The Problem is that I can't Insert new Job with specified ScheduleId!

 Job job = new Job();
 job.title= "blabla";
 job.description="xyz";
 job.scheduleId=1// can't have this!

 if (job.EntityState == EntityState.Detached)
 {
      myContext.AddToJobs(job);
 }
 myContext.SaveChanges();

Note: I have a row in Schedules table with scheduleId=1.

Best Answer

Doesn't the entity framework created a navigation property called Schedule?

You can use:

 Schedule schedule = // Get here the schedule with Id == 1;
 Job job = new Job();
 job.title= "blabla";
 job.description="xyz";
 job.schedule = schedule; //<-- Use the navigation property

 if (job.EntityState == EntityState.Detached)
 {
      myContext.AddToJobs(job);
 }
 myContext.SaveChanges();

The Id assignment is handled internally by the framework.


Here is a sample of a Job and a Schedule class created by Entity Framework with the POCO T4. Including the navigation property and the ScheduleId. Notice that the ScheduleId and Schedule Proprerties in the Job class are totaly binded one to the other.

public partial class Job
{
    #region Primitive Properties

    public virtual int Id
    {
        get;
        set;
    }

    public virtual int ScheduleId
    {
        get { return _scheduleId; }
        set
        {
            if (_scheduleId != value)
            {
                if (Schedule != null && Schedule.Id != value)
                {
                    Schedule = null;
                }
                _scheduleId = value;
            }
        }
    }
    private int _scheduleId;

    public virtual string Title
    {
        get;
        set;
    }

    public virtual string Description
    {
        get;
        set;
    }

    #endregion
    #region Navigation Properties

    public virtual Schedule Schedule
    {
        get { return _schedule; }
        set
        {
            if (!ReferenceEquals(_schedule, value))
            {
                var previousValue = _schedule;
                _schedule = value;
                FixupSchedule(previousValue);
            }
        }
    }
    private Schedule _schedule;

    #endregion
    #region Association Fixup

    private void FixupSchedule(Schedule previousValue)
    {
        if (previousValue != null && previousValue.Job.Contains(this))
        {
            previousValue.Job.Remove(this);
        }

        if (Schedule != null)
        {
            if (!Schedule.Job.Contains(this))
            {
                Schedule.Job.Add(this);
            }
            if (ScheduleId != Schedule.Id)
            {
                ScheduleId = Schedule.Id;
            }
        }
    }

    #endregion
}

public partial class Schedule
{
    #region Primitive Properties

    public virtual int Id
    {
        get;
        set;
    }

    public virtual string Description
    {
        get;
        set;
    }

    #endregion
    #region Navigation Properties

    public virtual ICollection<Job> Job
    {
        get
        {
            if (_job == null)
            {
                var newCollection = new FixupCollection<Job>();
                newCollection.CollectionChanged += FixupJob;
                _job = newCollection;
            }
            return _job;
        }
        set
        {
            if (!ReferenceEquals(_job, value))
            {
                var previousValue = _job as FixupCollection<Job>;
                if (previousValue != null)
                {
                    previousValue.CollectionChanged -= FixupJob;
                }
                _job = value;
                var newValue = value as FixupCollection<Job>;
                if (newValue != null)
                {
                    newValue.CollectionChanged += FixupJob;
                }
            }
        }
    }
    private ICollection<Job> _job;

    #endregion
    #region Association Fixup

    private void FixupJob(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (Job item in e.NewItems)
            {
                item.Schedule = this;
            }
        }

        if (e.OldItems != null)
        {
            foreach (Job item in e.OldItems)
            {
                if (ReferenceEquals(item.Schedule, this))
                {
                    item.Schedule = null;
                }
            }
        }
    }

    #endregion
}