|
dilkonika wrote: there are many articles on internet that suggest avoid ICloneable because of Shallow/Deep confusion. Yes, I would also avoid it. The solution is to simply name your Clone-Method/Interface differently and let its name express what it does (shallow/deep/configurable).
Are you aware that the method CopyTo(..) makes a shallow copy and ignores fields? Basically the only advantage it has over Object.MemberwiseClone[^] is that you have the possibility to specify whether "parent" properties should be copied or not.
So if you call it on a Student, it will copy the reference to his Result(s), not make a copy of his Result(s).
dilkonika wrote:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Core.dll
Additional information: Collection was modified; enumeration operation may not execute.
I assume you used this code:
newitm = New Myobject
currentobj.CopyTo(newitm, False)
context.MyObjects.Add(Newitm)
context.savechanges
in a foreach-loop where you iterated over objects (currentobj) in context ? You can't modify a collection while you're iterating over it using an Enumerator (which is what a foreach-loop does). Your options:
- Iterate using a for-loop, if the source collection has an indexer, in reverse direction.
- Make a copy of the collection and iterate over this copy while modifying the source collection.
- Create a new collection of objects to be added/deleted while iterating the source collection. When finished, add/delete the objects contained in the new collection to/from the source collection.
|
|
|
|
|
Thank you !
No , I heaven;t used my code in a for-each loop.
currentobj=context.myobjects.firstordefault.
and after continue with the code I posted.
|
|
|
|
|
Could be a quirk in EF. Please try this (two lines switched):
newitm = New Myobject
context.MyObjects.Add(newitm)
currentobj.CopyTo(newitm, False)
context.savechanges
|
|
|
|
|
Hello !
I'm using entity framework 6 with Vb.net 2013.
I'm trying to add an extension.
This is the code :
Imports System.ComponentModel
Imports System.Collections
Imports System.Data.Entity.Core.Objects.DataClasses
Imports System.Runtime.Serialization
Imports System.IO
Imports System.Reflection
Module Extensions
<System.Runtime.CompilerServices.Extension> _
Public Function Clone(Of T As EntityObject)(source As T) As T
Dim ser = New DataContractSerializer(GetType(T))
Using stream = New MemoryStream()
ser.WriteObject(stream, source)
stream.Seek(0, SeekOrigin.Begin)
Return CType(ser.ReadObject(stream), T)
End Using
End Function
End Module
But if I try to use like this :
Dim litm, newitm as MyObject
For Each litm In itemlist
newitm = litm.Clone()
...
Next
I'm getting this error :
'Clone' is not a member of 'TheProg.MyObject'
What's the problem ?
|
|
|
|
|
Your MyObject class doesn't have a Clone() method. It's not supplied to your class automatically, after all how would a default implementation know how to correctly copy your class? It wouldn't. YOU have to implement a Clone() method yourself.
|
|
|
|
|
sorry , but why the method Clone is not added as extension ? Have I done something wrong constructing the extension ?
|
|
|
|
|
Wow an I tired. It's 2:00am here. I didn't even notice the Clone method name...
What does your MyObject class look like? Are you using Database First, Code First, or what?
|
|
|
|
|
I'm using Database First.
Partial Public Class Myobject
Public Property id As Integer
Public property name as string
Public Overridable Property chld As ICollection(Of chld) = New HashSet(Of chld)
End Class
Partial Public Class chld
Public Property id As Integer
Public Property date1 as DateTime
Public Property quantity as Integer
Public Property ParentID as integer
Public Overridable Property MyObj1 As MyObject
End Class
|
|
|
|
|
It doesn't work because Database First entity objects inherit from Object , not EntityObject . Your current Close method would work just fine for a Code First EF model.
The only way to get the Clone() to work is to remove the "As EntityObject" restriction in the function header. Of course, this is going to make your Clone() method available for every type in the application.
|
|
|
|
|
I remove the "As entityobject".
Now , on runtime , I get this error on the line : ser.WriteObject(stream, source) :
An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll
Additional information: Type 'System.Data.Entity.DynamicProxies.MyObject_F2FFE64DA472EB2B2BDF7E143DE887D3845AD9D1731FD3107937062AC0C2E4BB' with data contract name 'MyObject_F2FFE64DA472EB2B2BDF7E143DE887D3845AD9D1731FD3107937062AC0C2E4BB:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
|
|
|
|
|
I don't know what you've got wrong because I can't replicated it.
This is the modified extension code I used:
Imports System.Data.Entity.Core.Objects.DataClasses
Imports System.Runtime.Serialization
Imports System.IO
Imports System.Runtime.CompilerServices
Imports System.Data.Objects
Module Extensions
<Extension>
Public Function Clone(Of T)(source As T) As T
Dim ser = New DataContractSerializer(GetType(T))
Using stream = New MemoryStream()
ser.WriteObject(stream, source)
stream.Seek(0, SeekOrigin.Begin)
Return CType(ser.ReadObject(stream), T)
End Using
End Function
End Module
|
|
|
|
|
This exactly the same code that I have used. but I get the error that I have posted before.
|
|
|
|
|
It just dawned on me why you're getting that error. The object you're trying to Clone is referencing other object in the database that haven't been re-hydrated by EF yet. That's where those strange looking proxy objects are coming from.
In order to get it to work, you have to load the objects being referenced before you try and Close the base object.
|
|
|
|
|
The way I'm getting the object that i want to clone is this :
-I have a listbox bound to a bindingsource (that have as datasource = (From t in context.Myobjects where t.id>5 select t ).Tolist
- The user select several items from listbox.
- I have a listitm=New list(of Myobject) , where i add one by one the items selected from listbox.
- After i have the code that i posted to my question :
Dim litm, newitm as MyObject
For Each litm In itemlist
newitm = litm.Clone()
...
Next
so in this situation , do you have an idea why i have those strange looking proxy objects like : MyObject_F2FFE64DA472EB2B2BDF7E143DE887D3845AD9D1731FD3107937062AC0C2E4BB
Thank you !
|
|
|
|
|
I just told you why. The object has a reference to another related object that EF hasn't loaded.
|
|
|
|
|
Actually , i have loaded all referenced object , but i think some of them are loaded only with some of the properties.
MyObjects - ob1
I have loaded ob1 like below :
Myob1list=(From t in context.ob1s
Select t.id,t.name).Tolist
May be this the problem , and if yes , what should i do ?
Thank you !
|
|
|
|
|
You have to load the child objects in your query:
Myob1list = (From t in context.ob1s.Include("chld")
Select t).ToList()
(I'm converting C# code from memory. I haven't touched VB.NET in a few years now.)
|
|
|
|
|
Sorry , but I'm using lazyloading.
and I've read that these proxy objects , are related with using of lazyloading.
So , why all other actions that I do with my objects works without problems, and this Clone action produce errors ?
|
|
|
|
|
dilkonika wrote: Sorry , but I'm using lazyloading.
and I've read that these proxy objects , are related with using of lazyloading.
Yeah, I can see that.
dilkonika wrote: So , why all other actions that I do with my objects works without problems, and this Clone action produce errors ?
Because the proxy classes are dynamically generated by EF and are not serializable.
|
|
|
|
|
dilkonika wrote: Sorry , but I'm using lazyloading. That doesn't mean you can't tell EF it should eager-load dependencies when you need it (which is what Include(..) does).
|
|
|
|
|
yes , but when I call the extension , these objects are already loaded in the way that I have described.
|
|
|
|
|
Hello I've managed to get the current tab for Google Chrome however how do I change that URL and made a navigation? I've done on IE but no luck for Opera and Firefox.
Example: Current urL: google.com will be yahoo.com upon active tab taken. Do I need to play something with the process of chrome? Thank you for any solution to be provide.
Dim procsChrome As Process() = Process.GetProcessesByName("chrome")
02
For Each chrome As Process In procsChrome
03
04
If chrome.MainWindowHandle = IntPtr.Zero Then Continue For
05
Dim elm As AutomationElement = AutomationElement.FromHandle(chrome.MainWindowHandle)
06
Dim elmUrlBar As AutomationElement = elm.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.NameProperty, "Address and search bar"))
07
If elmUrlBar IsNot Nothing Then
08
Dim patterns As AutomationPattern() = elmUrlBar.GetSupportedPatterns()
09
If patterns.Length > 0 Then
10
Dim val As ValuePattern = DirectCast(elmUrlBar.GetCurrentPattern(patterns(0)), ValuePattern)
11
If Not elmUrlBar.GetCurrentPropertyValue(AutomationElement.HasKeyboardFocusProperty) Then
12
MsgBox(LCase(val.Current.Value).Trim)
13
14
15
16
End If
17
Exit For
18
End If
19
End If
20
Next
|
|
|
|
|
Hello !
In vb.net 2013 , SQL server 2008R2 :
I have an active database , and a backup database ( .bak) file.
I want to compare the structure of these databases , to know if the structure is identical , if not to have a list with differencies
Can you give me some steps , how can I do this on Vb.net ?
Thank you !
|
|
|
|
|
|
Ok , but I want to know if how to do this with code in vb.net.
|
|
|
|