0

我在这里有点问题。我已经阅读了许多 SO 线程,但没有找到答案。

我正在使用断开连接的存储库模式进行数据访问,并使用 Code First EF。

POCO:

public class LineItem
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<LineItemCategoryMap> LineItemCategoryMaps { get; set; }
}

public class LineItemCategoryMap
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("LineItem")]
    public int LineItemId { get; set; }
    public LineItem LineItem { get; set; }

    [ForeignKey("Category")]
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

数据访问代码(更新):

public void Update(LineItem lineItem)
{
    using (var db = new DBContext())
    {
        db.LineItems.Attach(lineItem);
        db.Entry(lineItem).State = EntityState.Modified;
        db.SaveChanges();
    }
}

如果我有一个 LineItemCategoryMap 更新工作。但是,如果有两个项目都具有相同的 LineItemID,则会出现异常“ObjectStateManager 中已存在具有相同键的对象”。被抛出。

使用多个地图对象创建 LineItem 100%

如我所见, LineItem 正在尝试多次附加。它不应该只是重用 LineItem 吗?

4

1 回答 1

0

感谢@tschmit007 发现我正在尝试读取地图。

我通过删除 LineItemCategoryMap 上的 ID 并添加一个复合键来解决这个问题。

public class LineItemCategoryMap
{
    [Key, Column(Order = 0)]
    [ForeignKey("LineItem")]
    public int LineItemId { get; set; }
    public LineItem LineItem { get; set; }

    [Key, Column(Order = 1)]
    [ForeignKey("Category")]
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

不幸的是,更新代码有点不卫生,因为标记实体只保存标量和复杂属性,而不是导航属性(即关系)。 https://stackoverflow.com/a/14102487/101662

var lineItemToUpdate = (from obj in db.LineItems.Include("LineItemCategoryMaps")
                                             where obj.Id == lineItem.Id
                                             select obj).First();

lineItemToUpdate.LineItemCategoryMaps = lineItem.LineItemCategoryMaps;
lineItemToUpdate.LineItemDepartmentMaps = lineItem.LineItemDepartmentMaps;

db.Entry(lineItemToUpdate).CurrentValues.SetValues(lineItem);

db.SaveChanges();

我可以让它工作的唯一方法是获取具有上下文范围的对象,然后设置导航属性。

有谁知道更清洁的方法来做到这一点?也许没有额外的数据库调用。

我真的希望我可以更改导航属性。

于 2013-04-15T13:22:49.217 回答