1

I am trying to insert duplicate record using EF by below code

db.Set<TEntity>().AddRange(lstEntity);
db.SaveChanges();

lstEntity is a list of type TEntity.

Suppose, I have 6 elements in lstEntity, 3 of them are duplicate.

On the first line in AddRange it only adds 4 elements, because 3 elements were duplicate so it adds 1 (3 duplicated) + 3 distinct records so it becomes 4.

And therefore, it inserts only 4 records in the DB.

I need to allow this duplicate thing and want to insert all the 6 elements (duplicate and distinct both).

  • Share some dummy data and more code. – Sagar R Jul 13 '16 at 07:02
  • you can't have duplicates in your database. If you want to know the number of a certain item add a Count column or something like that, or add another index column and add it to your PK. Most DBMS do not support duplicate PK's, and EF doesn't either. – DevilSuichiro Jul 13 '16 at 07:57
  • PK's are not duplicate in this case, my PK is by default 0 which means insert. Technically all the elements are having PK as 0. – Mohammed Dawood Ansari Jul 13 '16 at 08:48
  • @MohammedDawoodAnsari : may I know what is the reason behind not using primary key? Performance ?\ – Sagar R Jul 13 '16 at 09:15
  • Primary is there at its place, I am inserting data here, so while inserting I keep the primary key value as 0 which ultimately means that I want to insert, if I will provide PK then it will be an update And in this case I am not updating, I am inserting values. P.S.: my PK is auto-generated identity in the database. – Mohammed Dawood Ansari Jul 13 '16 at 10:54
  • Did you set the "StoreGeneratedPattern" for entity's property correctly? If the PK is generated by database you should set "Computed". And of course the PK should be set on the entity class as well (not only for database table). – Kryszal Jul 13 '16 at 11:09
  • Thanks for the info. I tried to set it to "Computed" and also tried "Identity", nothing helped :( – Mohammed Dawood Ansari Jul 13 '16 at 11:52
  • It is not trivial to switch IDENTITY on and off. Check your database column is it actually an IDENTITY column? See this answer - http://stackoverflow.com/a/18917348/150342 – Colin Jul 13 '16 at 14:09

1 Answers1

4

Entity Framework he is doing his job correctly, the object services will find the duplicated items and insert them one time in db. Think about it! an entity represents a row in your table with an Id. You cannot insert the same row multiple times, you need a new primary key(Id).

You can clone your entity and add it to the DbContext or use this

Your name is arabic so I think you can understand the arabic langauge just watch my tutorial this will answer all your quesitons:

Video


Example for Clone:

public class City
{
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int Id { get; set; }

  public City Clone()
  {
    return (City)MemberwiseClone();
  }

}

public class MyDbContext : DbContext
{
  public MyDbContext(string connectionString)
        : base("name=" + connectionString)
  {
  }

  public DbSet<City> Cities { get; set; }
}

public static void Main(string[] args)
{
  Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyDbContext>());

  using (var myDbContext = new MyDbContext())
  {
    // This will add the city one time  => the bug
    var city = new City();

    var list = new List<City>();
    list.Add(city);
    list.Add(city);

    myDbContext.Cities.AddRange(list);
    myDbContext.SaveChanges();

    // This will add the city 2 times
    city = new City();
    var city2 = new City();

    list = new List<City>();
    list.Add(city);
    list.Add(city2);

    myDbContext.Cities.AddRange(list);
    myDbContext.SaveChanges();

    // This will add the clonned city1 and city=> Fix!
    var cityCloned1 = city.Clone();
    var cityCloned2 = city2.Clone();

    list = new List<City>();
    list.Add(cityCloned1);
    list.Add(cityCloned2);

    myDbContext.Cities.AddRange(list);
    myDbContext.SaveChanges();

  }

}

The result: enter image description here

Bassam Alugili
  • 16,345
  • 7
  • 52
  • 70
  • I understand, but what I mean is to insert all the duplicate records with different primary keys(auto-generated identity), so when I pass my list, all the element have pk as 0 which means to insert and Id should be autogenerated, I didn't mean to create 3 duplicate records with the same id, Id will be different but rest will be same – Mohammed Dawood Ansari Jul 13 '16 at 08:52
  • I am looking for some kind of configuration setting like dbContext.Configuration.AllowDuplicate = true, I dont want to hit database each time for each duplicate record. – Mohammed Dawood Ansari Jul 13 '16 at 08:53
  • duplicate for me when you are doing something like that: var list = new List(); list.Add(city); list.Add(city); when you add the ctiy list now to the database the entity framework will track all attached entities he will need the object hashcode and in this case the city in the list has the same hashcode that why the EF will give them both one Id. the soultion is easy just create a clone extension and before you add it to the list clone it. # – Bassam Alugili Jul 13 '16 at 09:25
  • @MohammedDawoodAnsari sorry i just found that you are from India the tutorial will not helping u – Bassam Alugili Jul 13 '16 at 09:34
  • I tried simple cloning and having same problem... Is there any clean way to insert duplicate records at one time without hitting database multiple times. or I am not doing it correctly, it would be grateful for me if someone can provide me some sample code, if any – Mohammed Dawood Ansari Jul 13 '16 at 11:01
  • Thanks for the code provided. I tried that code 1. added Clone() in my Entity class, 2. Then when I tried to do lstEntity.Clone() I am getting "'Entity' does not contain a definition for 'Clone' and no extension method 'Clone' accepting a first argument of type 'List' could be found", I tried to build it properly still getting the same issue :( – Mohammed Dawood Ansari Jul 14 '16 at 06:39
  • @MohammedDawoodAnsari it is work i will make a complete example for you. vote for the answer now and mark it later when the problem is solved – Bassam Alugili Jul 14 '16 at 09:12
  • That clone didn't work for me, but I tried with the 2nd approach ("This will add the city 2 times") provided in your code i.e. new memory for each duplicate items. And Eureka :) – Mohammed Dawood Ansari Jul 17 '16 at 05:41