Entity Framework: Adding object with foreign key
I have 2 tables Jobs and Schedule
Jobs
JobId - int,PK, Identity
ScheduleId - int, FK Title - varchar Description - varcharSchedules
ScheduleId - int,PK, Identity
Name - varcharThere 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();
开发者_C百科
Note: I have a row in Schedules table with scheduleId=1.
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
}
You can assign Schedule without actually loading Schedule object. Something like this:
db = new OneToManyEntities();
var address = new Address { Address1 = "Oakumber st", City = "Dallas", State = "Tx", Zip = "76111" };
address.CustomerReference.EntityKey = new EntityKey("OneToManyEntities.Customer","CustomerId",2);
db.AddToAddresses(address);
I don't like this approach, case you have to hardcode entity types in string :/ If anyone know how to do this without such hardcoding - please comment.
精彩评论