Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / February 2008

Tip: Looking for answers? Try searching our database.

Saving linq entity object in C: drive

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Andrus - 26 Feb 2008 20:47 GMT
I have subclassed entity object used to store settigns per every MDI form:

class  MyApp.EntityBase.Kontekst {
public string mybaseprop1 {  get { ... }  set { ... } }
...
}

class MyApp.EntityExtension.Kontekst:  MyApp.EntityBase.Kontekst{
public string property1 {  get { ... }  set { ... } }
...
}

class MyApp.Business.Kontekst: MyApp.EntityExtension.Kontekst {
public string method1 { ... }
...
}

I need to save / restore it in user computer. I tried to use the following
method to save

public static void Save(object obj, string id) {
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();
XmlSerializer formatter = new XmlSerializer(obj.GetType(), "mynsp");
....

but last line causes runtime error

There was an error reflecting type 'Kontekst'.

Types MyApp.EntityExtension.Kontekst' and 'Kontekst' both
use the XML type name, 'Kontekst', from namespace 'mynsp'. Use XML
attributes to specify a unique XML name and/or namespace for the type."

How to fix this ? Kontext classes are Linq classes generated automatically.

Is it possible to use some other form of saving or serialization or should I
add xml
attributes manually ?

Andrus.

.NET 3.5 WinForms.
Nicholas Paldino [.NET/C# MVP] - 27 Feb 2008 16:53 GMT
Andrus,

   Well, the exception message is pretty specific about the resolution to
the issue.  Because you use the same class name in different namespaces (XML
serialization doesn't take namespaces into account), you need to add an
XmlTypeAttribute to the classes and specify a different type name for each,
or if the type name is the same, specify a different namespace for each.
^Something^ has to be different between the three Kontekst types.

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

>I have subclassed entity object used to store settigns per every MDI form:
>
[quoted text clipped - 39 lines]
>
> .NET 3.5 WinForms.
Andrus - 27 Feb 2008 18:08 GMT
Nicholas,

>    Well, the exception message is pretty specific about the resolution to
> the issue.  Because you use the same class name in different namespaces
> (XML serialization doesn't take namespaces into account), you need to add
> an XmlTypeAttribute to the classes and specify a different type name for
> each, or if the type name is the same, specify a different namespace for
> each. ^Something^ has to be different between the three Kontekst types.

thank you.

Kontext classes are autogenerated.
I do'nt like to modify generated code manually since changes are lost if
classes are re-generated.

How to avoid manual changes ?
Is it possible to use DataContrct based or Binary serialization or some
other form to save data?
I need only to save/restore public property values.

Andrus.
Jon Skeet [C# MVP] - 27 Feb 2008 19:15 GMT
> >    Well, the exception message is pretty specific about the resolution to
> > the issue.  Because you use the same class name in different namespaces
[quoted text clipped - 13 lines]
> other form to save data?
> I need only to save/restore public property values.

Are they partial classes? If so, you can apply the XmlTypeAttribute to
another (non-generated) file for the same partial class.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrus - 27 Feb 2008 20:44 GMT
Jon,

> Are they partial classes? If so, you can apply the XmlTypeAttribute to
> another (non-generated) file for the same partial class.

Thank you. I was able to generate Kontekst types as partial classes and
apply
XmlTypeAttribute .
After that I got the error in this line

Unable to generate a temporary class (result=1).\r\nerror CS0012:
The type 'MyApp.EntityExtension.Kontekst' is defined in an assembly that is
not referenced.
You must add a reference to assembly 'EntityExtension, Version=1.0.0.0,
Culture=neutral,PublicKeyToken=null'.\r\n"

EntityExtension is dynamically generated assembly. It is loaded runtime.
If I use binary formatter (changed line to

IFormatter formatter = new BinaryFormatter();   )

serialization works OK.

How to fix this exception ?

Andrus.
Jon Skeet [C# MVP] - 27 Feb 2008 21:13 GMT
> Thank you. I was able to generate Kontekst types as partial classes and
> apply
[quoted text clipped - 15 lines]
>
> How to fix this exception ?

Hmm. If it's not a strongly named assembly, could you generate a
"dummy" assembly to reference at compile time, then make sure you've
got the real one at execution time? I don't know whether or not that
will work, but it *might*.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrus - 28 Feb 2008 11:39 GMT
Jon,

> Hmm. If it's not a strongly named assembly, could you generate a
> "dummy" assembly to reference at compile time, then make sure you've
> got the real one at execution time? I don't know whether or not that
> will work, but it *might*.

I'm currently using this approach.
My solution contains project which produces dummy  EntityExtension.dll
In start of Main() I delete this EntityExtension.dll and use AppDomain
AssemblyResolve() to provide new assembly.
Binary serializer and all Linq seems to work OK.

Only XmlSerializer causes this exception.
Maybe XmlSerializer requires assembly to have the same name,
EntityExtension?
I'm using the code below to create assembly in memory at runtime.
How to change this code so that it creates the assembly named
EntityExtension ?
Currently name contains some unique characters different in every time.

Andrus.

public static Assembly CreateAssembly() {

Microsoft.CSharp.CSharpCodeProvider provider = new
Microsoft.CSharp.CSharpCodeProvider
(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });

CompilerParameters compilerParameters = new CompilerParameters();
compilerParameters.GenerateInMemory = true;
compilerParameters.ReferencedAssemblies.Add("DataAccessBase.dll");
compilerParameters.ReferencedAssemblies.Add("Entity.dll");
compilerParameters.ReferencedAssemblies.Add("dblinq.postgresql.dll");
compilerParameters.ReferencedAssemblies.Add("dblinq.dll");
compilerParameters.ReferencedAssemblies.Add("System.dll");
compilerParameters.ReferencedAssemblies.Add(@"c:\Program Files\Reference
            Assemblies\Microsoft\Framework\v3.5\System.Data.Linq.dll");
compilerParameters.ReferencedAssemblies.Add(@"c:\Program Files\Reference
Assemblies\Microsoft\Framework\v3.5\System.Core.dll");
compilerParameters.ReferencedAssemblies.Add("System.Data.dll");
compilerParameters.ReferencedAssemblies.Add("System.Xml.dll");
string code = CreateWrapperAssembly();
CompilerResults compilerResults =
      provider.CompileAssemblyFromSource(compilerParameters, code);

if (compilerResults.Errors.HasErrors) {
 throw new ApplicationException("compile error");
 }
return compilerResults.CompiledAssembly;
}
Jon Skeet [C# MVP] - 28 Feb 2008 13:16 GMT
> > Hmm. If it's not a strongly named assembly, could you generate a
> > "dummy" assembly to reference at compile time, then make sure you've
[quoted text clipped - 14 lines]
> EntityExtension ?
> Currently name contains some unique characters different in every time.

Set the OutputAssembly property on the CompilerParameters.

By the way, if you're using C# 3 you should really look at using
object/collection initializers more - you're code would be a *lot*
simpler :)

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrus - 28 Feb 2008 14:47 GMT
Jon,

> Set the OutputAssembly property on the CompilerParameters.

I tried it but the problem persists. I tried to set it to invalid file name
by using
compilerParameters.OutputAssembly = "\000 ,.<>";

but this does not cause error. So it seems that this parameter is not used
in in-memory assembly generation.

How to force XmlSerializer() to find dynamically loaded assembly ?

> By the way, if you're using C# 3 you should really look at using
> object/collection initializers more - you're code would be a *lot*
> simpler :)

I changed code to

CompilerParameters compilerParameters = new CompilerParameters() {
{ "DataAccessBase.dll" },
{"Entity.dll"},
{"dblinq.postgresql.dll"},
{"dblinq.dll"},
{"System.dll"},
{@"c:\Program Files\Reference
Assemblies\Microsoft\Framework\v3.5\System.Data.Linq.dll"},
{@"c:\Program Files\Reference
Assemblies\Microsoft\Framework\v3.5\System.Core.dll"},
{"System.Data.dll"},
{"System.Xml.dll"} };

but got error
Cannot initialize type 'System.CodeDom.Compiler.CompilerParameters' with a
collection initializer because it does not implement
'System.Collections.IEnumerable'

How I can use object/collection initializers more ?

Andrus.
Jon Skeet [C# MVP] - 28 Feb 2008 15:14 GMT
> > Set the OutputAssembly property on the CompilerParameters.
>
[quoted text clipped - 4 lines]
> but this does not cause error. So it seems that this parameter is not used
> in in-memory assembly generation.

That's not necessarily the case. What was the generated assembly name
(when you ask the Assembly object itself) in this case?

> How to force XmlSerializer() to find dynamically loaded assembly ?

At this stage it's beyond my knowledge, I'm afraid.

> > By the way, if you're using C# 3 you should really look at using
> > object/collection initializers more - you're code would be a *lot*
[quoted text clipped - 19 lines]
> collection initializer because it does not implement
> 'System.Collections.IEnumerable'

Indeed. If you look at your original code, you don't try to add strings
to the CompilerParameters directly - you add them to the referenced
assemblies.

> How I can use object/collection initializers more ?

// Earlier, on one line:
const string ReferenceBase35 = @"c:\Program Files\Reference Assemblies
\Microsoft\Framework\v3.5\";

CompilerParameters compilerParameters = new CompilerParameters
{
   GenerateInMemory = true,
   ReferencedAssemblies =
   {
       "DataAccessBase.dll",
       "Entity.dll",
       "dblinq.postgresql.dll",
       "dblinq.dll",
       "System.dll",
       ReferenceBase35+"System.Data.Linq.dll",
       ReferenceBase35+"System.Core.dll",
       "System.Data.dll",
       "System.Xml.dll"
   }
};

Much clearer, if I do say so myself :)

(Untested, mind you...)

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrus - 28 Feb 2008 18:14 GMT
Jon,

> That's not necessarily the case. What was the generated assembly name
> (when you ask the Assembly object itself) in this case?

I was wrong. It changes the in-memory assembly name.

OutputAssembly = "EntityExtension";

Generates assembly name

CompiledAssembly = {EntityExtension, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null}

However XmlSerializer() call still causes exception. In this exception
assembly name is the same:

 Message="Unable to generate a temporary class (result=1).\r\nerror CS0012:
The type 'MyApp.EntityExtension.Kontekst' is defined in an assembly that is
not referenced. You must add a reference to assembly 'EntityExtension,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.\r\n"

So assembly names seems to be same.

>> How to force XmlSerializer() to find dynamically loaded assembly ?
>
> At this stage it's beyond my knowledge, I'm afraid.

Exception occurs in

System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns,
XmlSerializerCompilerParameters xmlParameters, Evidence evidence)

So XmlSerializer() uses dynamic compilation and this fails to resolve
dynamically loaded assembly.

> // Earlier, on one line:
> const string ReferenceBase35 = @"c:\Program Files\Reference Assemblies
> \Microsoft\Framework\v3.5\";

Excellent! Thank you very much.
In customer computer framework may be installed to directory than this.

How to determine the location of

c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\

in customer computer ?

Andrus.
Jon Skeet [C# MVP] - 28 Feb 2008 18:46 GMT
<snip>

> >> How to force XmlSerializer() to find dynamically loaded assembly ?
> >
[quoted text clipped - 7 lines]
> So XmlSerializer() uses dynamic compilation and this fails to resolve
> dynamically loaded assembly.

Mmm... one for more of an XML serialization expert, I'm afraid.

> > // Earlier, on one line:
> > const string ReferenceBase35 = @"c:\Program Files\Reference Assemblies
[quoted text clipped - 8 lines]
>
> in customer computer ?

Have a look in the registry at key

HKLM\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\v3.5 and value
"All Assemblies In".

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrus - 29 Feb 2008 08:08 GMT
Jon,

>> c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\
>>
[quoted text clipped - 4 lines]
> HKLM\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\v3.5 and value
> "All Assemblies In".

Why those assemblies are not put onto GAC ?
Looks very inconvenient to treat some assemblies differently than others.

Andrus.
Jon Skeet [C# MVP] - 29 Feb 2008 08:45 GMT
> >> c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\
> >>
[quoted text clipped - 7 lines]
> Why those assemblies are not put onto GAC ?
> Looks very inconvenient to treat some assemblies differently than others.

They *are* in the GAC. (Have a look in the GAC to verify - they're
certainly in my GAC.) They're also in the reference assemblies
directory so they're visible as actual files. (This is kinda handy when
it comes to using Reflector, for instance...)

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrus - 29 Feb 2008 14:30 GMT
Jon,

> They *are* in the GAC. (Have a look in the GAC to verify - they're
> certainly in my GAC.)

If so then dynamic compile must find them without directory prefix.

Why those assemblies require using directory prefix to be usable from
dynamic compile ?

> They're also in the reference assemblies
> directory so they're visible as actual files. (This is kinda handy when
> it comes to using Reflector, for instance...)

Why this directory exists and contains only those particular files?
Is it only for Reflector ?
Is so why other assemblies are not provided in this way ?

Andrus.
Jon Skeet [C# MVP] - 29 Feb 2008 14:38 GMT
> > They *are* in the GAC. (Have a look in the GAC to verify - they're
> > certainly in my GAC.)
>
> If so then dynamic compile must find them without directory prefix.

I'd have expected it to - at least if you specify the full assembly
name including version.

> Why those assemblies require using directory prefix to be usable from
> dynamic compile ?

Not sure. Try the full name.

> > They're also in the reference assemblies
> > directory so they're visible as actual files. (This is kinda handy when
[quoted text clipped - 3 lines]
> Is it only for Reflector ?
> Is so why other assemblies are not provided in this way ?

I think they've been moving towards this model rather than keeping them
in c:\Windows\Microsoft.NET\framework\vXXX

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrus - 29 Feb 2008 17:53 GMT
Jon,

>> Why those assemblies require using directory prefix to be usable from
>> dynamic compile ?
>
> Not sure. Try the full name.

http://msdn2.microsoft.com/en-us/library/s5bac5fx.aspx  describes that
reference directory is *not* included in compiler default search
directories:

The compiler searches for assembly references that are not fully qualified
in the following order:

 1.. Current working directory. This is the directory from which the
compiler is invoked.
 2.. The common language runtime system directory.
 3.. Directories specified by /lib.
 4.. Directories specified by the LIB environment variable

It seems that they forget to include reference directory to compiler default
search path in 3.5.

Andrus.
Andrus - 29 Feb 2008 17:54 GMT
Jon,

>> Why those assemblies require using directory prefix to be usable from
>> dynamic compile ?
>
> Not sure. Try the full name.

http://msdn2.microsoft.com/en-us/library/s5bac5fx.aspx  describes that
reference directory is *not* included in compiler default search
directories:

The compiler searches for assembly references that are not fully qualified
in the following order:

 1.. Current working directory. This is the directory from which the
compiler is invoked.
 2.. The common language runtime system directory.
 3.. Directories specified by /lib.
 4.. Directories specified by the LIB environment variable

It seems that they forget to include reference directory to compiler default
search path in 3.5.

Can we put this to wishlist ?

Andrus.
Jon Skeet [C# MVP] - 29 Feb 2008 19:03 GMT
> Jon,
>
[quoted text clipped - 20 lines]
>
> Can we put this to wishlist ?

I don't think the reference directory is *really* meant for that
purposee. You'd be better off loading it from the GAC with the full
name, IMO.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.