【问题标题】:Attach: Cannot add an entity with a key that is already in use附加:无法使用已在使用的密钥添加实体
【发布时间】:2010-07-17 18:49:50
【问题描述】:

我发现了一堆可能的重复项,但似乎没有一个真正遇到与我相同的问题。

我收到 DuplicateKeyException:无法使用已在使用的密钥添加实体。这是我的 SqlProductsRepository:

public class SqlProductsRepository : IProductsRepository
{
    private Table<Product> productsTable;
    private Table<Image> imagesTable;

    public SqlProductsRepository(string connectionString)
    {
        productsTable = (new DataContext(connectionString)).GetTable<Product>();
        imagesTable = (new DataContext(connectionString)).GetTable<Image>();

        // Populate all of the images for each product found
        foreach (Image image in imagesTable)
        {
            productsTable.Where<Product>(x => x.ProductID == image.ProductID).FirstOrDefault().Images.Add(image);
        }
    }

    public IQueryable<Product> Products
    {
        get { return productsTable; }
    }

    public IQueryable<Image> Images
    {
        get { return imagesTable; }
    }

    public void SaveProduct(Product product)
    {
        EnsureValid(product, "Name", "Description", "Category", "Price");

        if (product.ProductID == 0)
            productsTable.InsertOnSubmit(product);
        else
        {            
            productsTable.Attach(product);

            productsTable.Context.Refresh(RefreshMode.KeepCurrentValues, product);
        }

        productsTable.Context.SubmitChanges();
    }

问题出在添加 imagesTable 的某个地方。如果我为没有图像的产品执行此操作,则没有问题。只有当产品具有图像时才会出现此问题。正如您所期望的那样,产品和图像非常基本:

[Table(Name = "Images")]
public class Image
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
    public int ImageID { get; set; }

    [Column] public int ProductID { get; set; }
    [Column] public int SortOrder { get; set; }
    [Column] public string Path { get; set; }
}

[Table(Name = "Products")]
public class Product : IDataErrorInfo
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync=AutoSync.OnInsert)]
    public int ProductID { get; set; }

    [Column] public string Name { get; set; }
    [Column] public string Description { get; set; }
    [Column] public decimal Price { get; set; }
    [Column] public string Category { get; set; }

    private IList<Image> _images;
    public IList<Image> Images {
        get
        {
            if (_images == null)
                _images = new List<Image>();
            return _images;
        }
        set
        {
            _images = value;
        }
    }

这个问题要了我的命。我尝试了各种变体,包括首先获取原始产品并将其作为 Attach 的第二个参数传递(除了仅将“true”作为第二个参数传递)。

有谁知道这是什么原因造成的?

【问题讨论】:

    标签: sql-server asp.net-mvc linq-to-sql


    【解决方案1】:

    第一次观察。假设基于您使用 LINQ to SQL 的标签,请尝试使用单个数据上下文和 LoadOptions。类似(未经测试):

    private Table<Product> productsTable;
    private Table<Image> imagesTable;
    private DataContext context;
    
    public SqlProductsRepository(string connectionString)
    {
        context = new DataContext(connectionString);
        var loadOptions = new DataLoadOptions();
        loadOptions.LoadWith<Product>(item => item.Image);
        context.LoadOptions = loadOptions;
        productsTable = context.GetTable<Product>();
    }
    

    【讨论】:

    • 这大致就是我所做的。我实际上决定合并 Images 表并将其放入 Products 中以逗号分隔的列中。问题解决了。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    • 2019-08-15
    • 2015-10-14
    • 1970-01-01
    相关资源
    最近更新 更多