2010-07-17 5 views
0

J'ai trouvé un tas de doublons possibles autour de cela mais aucun ne semblait vraiment avoir le même problème que celui que j'ai.Joindre: Impossible d'ajouter une entité avec une clé déjà utilisée

Je reçois une exception DuplicateKeyException: Impossible d'ajouter une entité avec une clé déjà utilisée. Voici mon 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(); 
    } 

Le problème est quelque part autour de la imagesTable ajoute dans Si je fais cela pour un produit qui n'a pas d'image, il n'y a pas de problème. Ce n'est que lorsqu'un produit comporte des images que ce problème se produit. Le produit et l'image sont assez basiques, comme vous vous y attendez:

[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; 
     } 
    } 

Ce problème me tue. J'ai essayé toutes sortes de variations, y compris l'obtention du produit original en premier et le passage en tant que second paramètre de Attach (en plus de simplement passer le "vrai" comme second paramètre).

Est-ce que quelqu'un sait ce qui pourrait causer cela?

Répondre

0

Première observation. En supposant, en fonction des balises que vous utilisez LINQ to SQL, essayez d'utiliser un seul contexte de données et LoadOptions. Quelque chose comme (non testé):

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>(); 
} 
+0

C'est à peu près ce que j'ai fait. J'ai en fait décidé de consolider la table Images et de la placer dans une colonne délimitée par des virgules dans Products. Problème résolu. :) – macca1

Questions connexes