实体框架 - 代码优先 - 更新不会更改外键

时间:2014-05-23 08:56:34

标签: entity-framework ef-code-first entity-framework-5

我找不到任何更改外键的代码。如何告知上下文外键已更改以便更新数据库?我一直试图让它工作2个月了:

以下是模型:

namespace MyApp.WebApi.Models
{

public class Project
{
    public int ProjectId { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }

    // Foreign Key - Project Status

    public virtual ProjectStatus ProjectStatus { get; set; }
}

public class ProjectStatus
{
    public int ProjectStatusId { get; set; }
    public string Name { get; set; }
}

public class HerculesWebApiContext : DbContext
{
    public HerculesWebApiContext() : base("name=HerculesWebApiContext") { }

    public DbSet<Project> Projects { get; set; }
    public DbSet<ProjectStatus> ProjectStatuses { get; set; }


    protected override void OnModelCreating(DbModelBuilder modelBuilder) { }
}
}

这是Web API的控制器:

namespace MyApp.WebApi.Controllers
{
public class ProjectController : ApiController
{
    private HerculesWebApiContext db = new HerculesWebApiContext();

    public void PutProject(int id, [FromBody]Project project)
    {
        if (!ModelState.IsValid) throw new HttpResponseException(HttpStatusCode.BadRequest); 
        if (id != project.ProjectId) throw new HttpResponseException(HttpStatusCode.BadRequest); 


        // I need some code here to tell EF that the FK has changed

        db.Entry(project).State = EntityState.Modified;


        // Try catch around this

        db.SaveChanges();
    }

上述代码不会更新项目状态外键,即使它已传递给函数的JSON对象已更改。该对象的返回格式与Web API提供的格式相同,但更新了Project Status对象:

[{"ProjectStatus":{"ProjectStatusId":2,"Name":"Started"},"ProjectId":3,"Description":"test description","Name":"test project"}]

我试过了:

db.Projects.Attach(db.Projects.Single(c => c.ProjectId == project.ProjectId));

        ((IObjectContextAdapter)db).ObjectContext
            .ApplyCurrentValues("Projects", project);

我也尝试过:

db.Entry(project.ProjectStatus).CurrentValues.SetValues(new ProjectStatus { ProjectStatusId = project.ProjectStatus.ProjectStatusId });

我也试过这个:

var per = new ProjectStatus { ProjectStatusId = project.ProjectStatus.ProjectStatusId }; // create the stub
db.ProjectStatuses.Attach(per);
db.Entry(project.ProjectStatus).CurrentValues.SetValues(per);

这些是从我的模型自动创建的表T-SQL文件:

项目表:

CREATE TABLE [dbo].[Projects] (
[ProjectId]                     INT            IDENTITY (1, 1) NOT NULL,
[Description]                   NVARCHAR (MAX) NULL,
[Name]                          NVARCHAR (MAX) NULL,
[ProjectStatus_ProjectStatusId] INT            NOT NULL,
CONSTRAINT [PK_dbo.Projects] PRIMARY KEY CLUSTERED ([ProjectId] ASC),
CONSTRAINT [FK_dbo.Projects_dbo.ProjectStatus_ProjectStatusId] FOREIGN KEY ([ProjectStatus_ProjectStatusId]) REFERENCES [dbo].[ProjectStatus] ([ProjectStatusId]) ON DELETE CASCADE

项目状态表

CREATE TABLE [dbo].[ProjectStatus] (
[ProjectStatusId] INT            IDENTITY (1, 1) NOT NULL,
[Name]            NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.ProjectStatus] PRIMARY KEY CLUSTERED ([ProjectStatusId] ASC)
);

1 个答案:

答案 0 :(得分:1)

你需要做两件事。首先明确说明每个类的主键。

[Key]属性添加到

Project课程,在public int ProjectId { get; set; }

行之上

ProjectStatus课程,在public int ProjectStatusId { get; set; }

行之上

其次,将外键的属性添加到Project类。添加以下行:

public int ProjectStatusId { get; set; }