实体框架:使用外键添加对象

时间:2010-08-12 15:15:34

标签: c# sql-server entity-framework

我有2个工作表和工作表

工作

JobId - int,PK,Identity
ScheduleId - int,FK
标题 - varchar
描述 - varchar

时刻表

ScheduleId - int,PK,Identity
名称 - varchar

删除时级联有一对多的关系。

当我创建实体模型时,生成的作业模型会删除ScheduleId字段。

问题是我无法使用指定的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();

注意:我在Scheduleles表中有一行,其中scheduleId = 1。

2 个答案:

答案 0 :(得分:1)

实体框架是否创建了名为Schedule?

的导航属性

您可以使用:

 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();

Id分配由框架内部处理。


以下是Entity Framework使用POCO T4创建的Job和Schedule类的示例。包括导航属性和ScheduleId。请注意,Job类中的ScheduleId和Schedule Proprerties是完全绑定到另一个。

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
}

答案 1 :(得分:1)

您可以在不实际加载Schedule对象的情况下分配Schedule。像这样:

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);

我不喜欢这种方法,如果你必须在字符串中硬编码实体类型:/如果有人知道如何在没有这种硬编码的情况下执行此操作 - 请发表评论。