LINQ初始化程序引发“ObjectStateManager中已存在具有相同键的对象”。

时间:2014-02-21 04:54:33

标签: c# entity-framework

        DataLayer.Image image = new DataLayer.Image();
        image.DateCreated = DateTime.Now;
        image.ImageData = (byte[])Session[STR_UploadedImage];
        image.TimeStamp = imageDateTimeUserControl.DateTime;
        image.Incident_Id = int.Parse(Request.QueryString[STR_IncidentId]);
        image.CreatedBy_Id = db.Employees.First(em => em.Username == Context.User.Identity.Name).Id;
        db.Images.AddObject(image);
        foreach (NumericTag tag in tags.OfType<NumericTag>())
        {
            var numericTags = db.Tags.OfType<NumericTag>().Where(t => t.TagType.Id == tag.TagType.Id && t.Value == tag.Value);
            image.Tags.Add(numericTags.Any() ? numericTags.First() : new NumericTag
            {
                TagType = tag.TagType,
                Value = tag.Value
            });
        }
        foreach (TextualTag tag in tags.OfType<TextualTag>())
        {
            var textualTags = db.Tags.OfType<TextualTag>().Where(t => t.TagType.Id == tag.TagType.Id && t.Description == tag.Description);
            image.Tags.Add(textualTags.Any() ? textualTags.First() : new TextualTag
            {
                TagType = tag.TagType,
                Description = tag.Description
            });
        }
        db.SaveChanges();
        detailsPanel.Visible = false;
        imagePanel.Visible = false;
        uploadPanel.Visible = true;

我正在尝试将属性(标签)添加到图像中,因为它已添加到数据库中。我有一个存储在ViewState中的临时标签列表。当行image.Tags.Add尝试添加现有标记时,它可以正常工作,但是当它执行初始化程序时,它会抛出“ObjectStateManager中已存在具有相同键的对象”。异常。

有谁看到我做错了什么?

但是,从另一个页面添加标签到数据库中现有图像的方法可以正常工作:

TagType tagType = tagTypes[tagTypeDropDownList.SelectedIndex];
int numericTagValue;
if (tagType is NumericTagType & !int.TryParse(tagDecriptionTextBox.Text, out numericTagValue))
{
    ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "TagError",
        string.Format("alert('Only numeric values are valid for tags of type {0}.');", tagType.Name), true);
    return;
}
foreach (var imageId in imageCheckBoxList.Items.Cast<ListItem>().Where(i => i.Selected)
    .Select(i => int.Parse(i.Value)))
{
    var image = db.Images.First(i => i.Id == imageId);
    var tags = db.Tags.AsEnumerable().Where(t => t.TagType.Id == tagType.Id
                    && (t is TextualTag ?
                    ((TextualTag)t).Description == tagDecriptionTextBox.Text :
                    ((NumericTag)t).Value == numericTagValue));
    if (tags.Any())
    {
        var tag = tags.First();
        if (!image.Tags.Select(t => t.Id).Contains(tag.Id))
            image.Tags.Add(tag);
    }
    else
    {
        if (tagType is NumericTagType)
            image.Tags.Add(new NumericTag
                {
                    TagType = (NumericTagType)tagType,
                    Value = numericTagValue
                });
        else
            image.Tags.Add(new TextualTag
                {
                    TagType = (TextualTagType)tagType,
                    Description = tagDecriptionTextBox.Text
                });
    }
    db.SaveChanges();
}
attributeListView.DataBind();
tagDecriptionTextBox.Text = "";

1 个答案:

答案 0 :(得分:0)

本声明:

new TextualTag
{
    TagType = tag.TagType,
    Description = tag.Description
});

不授予对象单一性。您必须为新标记指定主键。

如果您正在使用Guids,这很简单。 Guid.NewGuid()解决了所有问题。

如果您将intIdentity一起使用,则需要使用其他属性制作彼此不同的对象。