views:

60

answers:

3

How would you do this (pseudo code): product1.Orders.AddRange(product2.Orders);

However, the function "AddRange" does not exist, so how would you copy all items in the EntityCollection "Orders" from product2 to product1?

Should be simple, but it is not...

A: 

Yes, the usual collection related functions are not there.

But,
1. Did you check CopyTo method?
2. Do you find any problem with using the iterator? You know, GetEnumerator, go through the collection and copy the entities?

The above two can solve your problems. But, I'm sure in .NET 3.0+ there would be compact solutions.

My answers are related to .NET 2.0

Nayan
Thanks for your help Nayan. 1) product2.Orders.CopyTo(product1.Orders); //does not work, CopyTo does not accept an EntityCollection as an argument.2) foreach(Order order in product2.Orders){ product1.Orders.Add(order); //doesn't work}>> "System.InvalidOperationException : Collection was modified; enumeration operation may not execute."
I saw your solution ans expected something like that only. I did not say that my answer was precise but rather hinted to possible solution :) Cheers!
Nayan
A: 

The problem is deeper than you think.

Your foreach attempt fails, because when you call product1.Orders.Add, the entity gets removed from product2.Orders, thus rendering the existing enumerator invalid, which causes the exception you see.

So why does entity get removed from produc2? Well, seems quite simple: because Order can only belong to one product at a time. The Entity Framework takes care of data integrity by enforcing rules like this.

If I understand correctly, your aim here is to actually copy the orders from one product to another, am I correct?

If so, then you have to explicitly create a copy of each order inside your foreach loop, and then add that copy to product1.

For some reason that is rather obscure to me, there is no automated way to create a copy of an entity. Therefore, you pretty much have to manually copy all Order's properties, one by one. You can make the code look somewhat more neat by incorporating this logic into the Order class itself - create a method named Clone() that would copy all properties. Be sure, though, not to copy the "owner product reference" property, because your whole point is to give it another owner product, isn't it?

Anyway, do not hesitate to ask more questions if something is unclear. And good luck.

  • Fyodor
Fyodor Soikin
Thanks Fyodor, didn't think about that one. The new Entity Framework looked so easy to me with all those nice wizards...
A: 

Based on the previous two answers, I came up with the following working solution:

public static void AddRange<T>(this EntityCollection<T> destinationEntityCollection,
                                       EntityCollection<T> sourceEntityCollection) where T : class  
    {
        var array = new T[sourceEntityCollection.Count()];

        sourceEntityCollection.CopyTo(array,0);


        foreach (var entity in array)
        {
            destinationEntityCollection.Add(entity);
        }
    }
Note that this solution doesn't actually COPY orders - only MOVES them. That is to say, when you call product1.Orders.AddRange(product2.Orders), your product1 ends up with all the orders, but product2 ends up with none. Is that what you were trying to achieve?
Fyodor Soikin
`this` in argument? Is it a typo?
Nayan
@Fyodor Soikin: That's what I'm trying to achieve. "product2" will never be stored in the database. Only "product1" will be stored.@Nayan: "AddRange" is a C# "extension" method.