0

What I'm trying to achieve is generate a project dynamically from c# classes generated by me. This classes' content are a similar content of code-first code generation of entity framework.The content looks as follows:

namespace ElasticTables
{
    using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.ComponentModel.DataAnnotations.KeyAttribute;

    [Table("address")]
    public partial class address
    {

        [Key]
        public decimal id { get; set; }

        public string name { get; set; }
    }
}

I generate this files from the tables in my database, and then try to compile it programmatically so that I can reference the generated project in another project that works with an API.

The main errors while compiling is:

The type or namespace name 'KeyAttribute' does not exist in the namespace 'System.ComponentModel.DataAnnotations' (are you missing an assembly reference?)

The type or namespace 'Key' could not be found

The type or namespace 'Table' could not be found.

I'm using 'CSharpCodeProvider'

    var provider = new CSharpCodeProvider();
    var options  = new CompilerParameters
    {
        OutputAssembly  = "ElasticTables.dll",
        CompilerOptions = "/optimize"
    };

And I have the following referenced Assemblies

options.ReferencedAssemblies.Add(Directory.GetCurrentDirectory() + "\\EntityFramework.dll");
options.ReferencedAssemblies.Add(Directory.GetCurrentDirectory() + "\\EntityFramework.SqlServer.dll");

I have an string array with the files' paths called sources, and I try to compile with the following line

CompilerResults results = provider.CompileAssemblyFromFile(options, sources);

Help is much appreciated.

Community
  • 1
  • 1
Josué Zatarain
  • 791
  • 6
  • 21

2 Answers2

0

You need to reference all needed assemblies (as the error says), so you need to add, I'd say at the very least:

options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.ComponentModel.DataAnnotations.dll");

Others might be needed

About the comment in your question, yes, you should specify options.OutputAssembly

Also, in your generated code:

using System.ComponentModel.DataAnnotations.KeyAttribute;

KeyAttribute is not a namespace, so it'll probably give an error when compiling.

I'd also take the usings before the namespace. This is not strictly needed and not an error, but it's the common practice (and that way you are sure the referenced assemblies are from the global namespace, and not childs of the namespace your class is in [just in case there's a name conflict])

Jcl
  • 27,696
  • 5
  • 61
  • 92
  • Your answer worked; I am not aware where does this assembly is positioned (its directory), is it perhaps located in the .net framework folder? – Josué Zatarain Apr 22 '16 at 14:33
  • The referenced assemblies, unless you specify a full path, are looked for in the GAC (the `Global Assembly Cache`), typically `%windir%\Microsoft.NET\assembly\GAC_[32|64]`. You can read more about the GAC [on the MSDN](https://msdn.microsoft.com/en-us/library/yf1d93sz(v=vs.110).aspx). – Jcl Apr 22 '16 at 14:34
  • Thanks for the feedback :). – Josué Zatarain Apr 22 '16 at 14:36
  • @JosuéZatarain you'll find the most commonly used references if you open a default Visual Studio project template and look in the `References` folder in the solution explorer (including the `System` one that I put in the answer). You may want to see if you need any others :) – Jcl Apr 22 '16 at 14:37
0

Have you tried to add also a reference to "System.dll" and "System.ComponentModel.DataAnnotations.dll" (for the System.ComponentModel stuff) ? (as you may indeed be missing an assembly reference)

options.ReferencedAssemblies.Add(
    Path.Combine(
  Directory.GetCurrentDirectory(),
    "System.ComponentModel.DataAnnotations.dll"));
Diego B
  • 21
  • 3