EntityFramework创建新项目,引用另一个

时间:2015-05-13 14:51:05

标签: c# entity-framework

我有2个模型类,如下所示:

public class Collection
{
    public int Id { get; set; }
    public int CenterId { get; set; }
    public string Reference { get; set; }

    public Status Status { get; set; }
}

public class Status
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

状态表填充了5种状态。当我创建一个集合时,我希望能够将状态附加到集合中。 我有这个BindingViewModel:

public class CollectionBindingModel
{
    public int Id { get; set; }

    [Required]
    [Display(Name = "Center id")]
    public int CenterId { get; set; }
    public string Reference { get; set; }

    public Status Status { get; set; }
}

当我打电话给我的控制器时,我希望它能用外键指向正确的状态来创建集合。相反,它创造了状态.... 这是控制器中的代码:

/// <summary>
/// Creates the collection
/// </summary>
/// <param name="model">The collection which is to be saved</param>
/// <returns>The collection that was saved to the database</returns>
[HttpPost]
[Route("")]
public IHttpActionResult Create(CollectionBindingModel model)
{

    // Save our collection
    return Save(model);
}

/// <summary>
/// Creates or updates the collection
/// </summary>
/// <param name="model">The collection which is to be saved</param>
/// <returns>The collection that was saved to the database</returns>
private IHttpActionResult Save(CollectionBindingModel model)
{
    // If our ModelState is invalid, return a bad request
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // Assign our binding model to a new model
    var collection = new Collection()
    {
        Id = model.Id,
        CenterId = model.CenterId,
        Reference = model.Reference,
        Status = model.Status
    };

    // Save our collection
    if (collection.Id == 0)
        this.DbContext.Collections.Add(collection);
    else
        this.DbContext.Entry<Collection>(collection).State = EntityState.Modified;

    // Save the changes
    this.DbContext.SaveChanges();

    // Get the location header
    var locationHeader = new Uri(Url.Link("GetById", new { centerId = collection.CenterId, id = collection.Id }));

    // Return the result
    return Created(locationHeader, collection);
}

如何让它使用系统中已有的正确状态?

4 个答案:

答案 0 :(得分:1)

您可以使用三种方法:

  1. 如果您想将现有状态添加到新收藏集,您可以根据来自viewmodel的数据从dbContext获取状态。

    var status = dbContext.Set()。SingleOrDefault(s =&gt; s.Id == model.Status.Id);

    collection.Status = status;

  2. 您可以使用方法dbContext将您的状态从viewmodel附加到dbContext.Set<Status>.Attach(status),然后将此附加状态分配给您的收藏:

    dbContext.Set.Attach(model.Status);

    collection.Status = model.Status;

  3. 您可以将外键属性StatusId添加到Collection实体,并将此StatusId设置为Id Status _not _ 将状态设置为集合的状态属性。

    public class Collection
    {
    public int Id { get; set; }
    public int CenterId { get; set; }
    public string Reference { get; set; }        
    
    [ForegnKey("Status")]
    public int StatusId{get;set;}
    public Status Status { get; set; }
    }
    

答案 1 :(得分:0)

您在帖子中获得的状态对象是由绑定创建的新对象。您应该将状态ID放在viewModel中,并从db加载相应的状态对象并引用新集合中的状态:

public class CollectionBindingModel
{
    public int Id { get; set; }

    [Required]
    [Display(Name = "Center id")]
    public int CenterId { get; set; }
    public string Reference { get; set; }
    public string StatusName {get; set;}
    **public int StatusId { get; set; }**
}

也许你必须在视图中使用隐藏字段来转发id的值。

答案 2 :(得分:0)

它认为您传递的Status对象是新对象,因此会重新添加它。

修正:

  1. 即使您已拥有状态,也要从数据库加载状态。这将导致返回的Status对象附加到DbContext,您可以使用它。

  2. 使用Status

  3. 手动附加context.Statuses.Attach(model.Status)对象

    这两种方法都会导致model.Status对象被附加(并因此被跟踪)。

答案 3 :(得分:0)

即使我已经用正确的答案标记了基里尔,但我想我会发布我实际做过的事情。 我保持所有模型都一样,我唯一改变的是保存功能。 我将状态更改为:

// Assign our binding model to a new model
var collection = new Collection()
{
    Id = model.Id,
    CenterId = model.CenterId,
    Reference = model.Reference,
    Status = this.DbContext.Statuses.Attach(model.Status)
};

这已经奏效了。