views:

316

answers:

3

Hi!

I'm trying to copy all object attibutes to another object, fox example:

Person p1 = new Person();
p1.name = "John";
p1.sex = 'M';
Person p2 = new Person();
p2 = Util.Clone(p1);

The problem is that Person entity has an identity PK 'codPerson' and I don't want to copy this PK. Is there a way to clone/copy an object, but don't copy its PK attribute??

Thanks!!!

A: 

You could manually set the properties on the new object to be equal to the old one.

For example:

Person p2 = new Person {
    Name = p1.Name,
    Gender = p1.Gender,
    //...
};
SLaks
But SLaks, I don't want to copy manually. Imagine if it is an object that has 100 attributes?!?! I've tested some solutions, but I need to know how can I tell if an attribute is a PK
AndreMiranda
If you have an object with 100 attributes you have a serious design problem, either in your code or in your database.
Konamiman
I think that's not the point of this question...
AndreMiranda
+1  A: 

Perhaps you might consider the following:

  1. Ensure Util.Clone(Person p) doesn't copy the codPerson attribute
  2. Clear the attribute after the Clone method is called
  3. Create a new Person object while specifically initializing specific properties.
mezoid
But what If I don't know which fields are PK? I know I have to find if a field is PK, but I don't how to do this...
AndreMiranda
As I say in my answer - if its a generic object how *can* one know what the PK is which in turn suggests that its not a generic object and to be more helpful we need to know more about said object (-:
Murph
You're code won't be able to determine which field is the primary key unless you tell it which one it is. Consider what Murph said concerning using an annotation of some sort to identify the PK: http://stackoverflow.com/questions/1594149/how-can-i-clone-or-copy-a-object-to-another-one-but-dont-copy-pk-attribute/1594231#1594231
mezoid
+1  A: 

At the most basic level you can't - given an arbitrary object o (and the question implies you're looking for generic solutions) you have no way to determine which field is a primary key.

So you step up a level - by adding some constraints i.e. that you will inform your tools what the primary key field is (or fields are) and hence enable use of a generic method.

So, you could explicitly specify the PK field (name) to the code that does the clone (I assume that you're using reflection to avoid explicitly copying all the fields). You could identify the PK by using annotation of some sort on the classes being cloned and have the clone code exclude properties with the relevant annotation (the annotation implies that the field won't be cloned). There may be other methods

You mention Linq - are you using a specific bit of Linq ?

Beyond that there's not a lot one can suggest without more details - ah but the question is tagged with Linq to SQL (which I missed) ok...

There's nothing obvious in a Linq to SQL class that will help - nor with the "table" but a quick look at the generated code in .designer.cs shows that a key field has annotations similar to the following (taken from a set of classes I have to hand):

[Column(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]

Therefore when you're do your reflection on the class to enumerate the properties to copy you'll want to look for the column and the "IsPrimaryKey" property within the column - unfortunately the details of how to do that are some distance outside my comfort zone!

Murph
You've said about using reflection... how can I use it without know the Entity type?
AndreMiranda
Call `entity.GetType()`
SLaks
Sorry, but where I use this?
AndreMiranda
It would have to be in the clone method (if the clone method is generic in a utility). It seems to me that at this point you may be pushing the limits of what it is sensible to attempt.
Murph