0

I want to have a duplicate from an object that field Id must be specified with a database that means I shouldn't define it directly.

I find my object and copy all parameters into another object exclude the id field

but it doesn't look list the best way to copy all fields into another object to exclude just the id field.

I have done it this way but looking for a better way

            /*duplicate product*/

            products product = db.products.Find(id);
            products duplicateProduct = new products {
                title = product.title,
                stock_count=product.stock_count,
                price=product.price,
                category_id=product.category_id,
                context=product.context,
                Featured=product.Featured,
                ForSale=product.ForSale,
                discount_prcent=product.discount_prcent          
            };
            db.products.Add(duplicateProduct);
            db.SaveChanges();

            /*End duplicate product*/
  • 1
    You could create an extension method `Copy` so you only need to define it once – Tim Schmelter Apr 17 '21 at 08:07
  • why extension method?I can use just a method. –  Apr 17 '21 at 08:13
  • Well, i would want to keep that entity model free from functional code. But do as you wish. I like extensions here because they allow me to write `products duplicateProduc = product.Copy();` without actually putting this code into `products`. Note that this entity class should be singular and pascal case. – Tim Schmelter Apr 17 '21 at 08:15
  • 1
    If id values are always going to be different from Product to Product when you copy one product to another, you can use a copy constructor. Let me know if you want to learn what I mean in more detail. – Ali Ihsan Elmas Apr 17 '21 at 08:19
  • @AliIhsanElmas please explain more about copy constructor and the way you do this. –  Apr 17 '21 at 08:22
  • @amirkian: copy-constructor is just a variant of a factory method like the `Copy` method that i have mentioned above. Actually the factory method calls the copy constructor, so you have both ways which do the same. But i'd prefer `Copy` since a constructor has no name, so if you look at your code later you might not understand what happens there. – Tim Schmelter Apr 17 '21 at 08:28

2 Answers2

0

Okay, there is more than one solution to this problem. As I said in the comment if you want ID values to always be different from each other when you create a copy of the product you can use Copy Constructor. Here is the code snippet for that:

 public class Program
{
    public static void Main()
    {
        Product product= new Product()
        {
            Property1=1,
            Property2=2,
            ID=3
        };
        
        Product copyProduct=new Product(product);
    }
}

public class Product
{
    public int Property1 {get;set;}
    public int Property2 {get;set;}
    public int ID {get;set;}
    
    public Product()
    {
    }
    
    public Product(Product product)
    {
        Property1=product.Property1;
        Property2=product.Property2;
    }
}

But be careful when you are copying reference values. You may want to have a look at this article Shallow copy vs. Deep Copy

Ali Ihsan Elmas
  • 174
  • 4
  • 15
0

Dreaming

If c# 9's record type could be used as Entity Framework object we could do:

var a2 = a1 with { Id = 2 };

Current solution

Copying properties may seem tedious but it's OK. It does the job.

Constructors are preferred to type initialisers { A = a ... because if Products gets a new field existing code will not copy all fields and there will be no compile errors.

AsNoTracking

Maybe following would work:

products product = db.products.AsNoTracking().Find(id);
product.Id = null;
db.products.Add(duplicateProduct);
db.SaveChanges();
tymtam
  • 31,798
  • 8
  • 86
  • 126
  • product.Id cant be null due primary key constraint –  Apr 17 '21 at 17:05
  • I'm confused, you question is about creating a product with no id because the db manages ids. After .Add + SaveChanges the id will no be null anymore. – tymtam Apr 17 '21 at 21:05