Search code examples
c#entity-frameworknamespacesdata-annotationscsharpcodeprovider

Namespace not found error when compiling assembly from files


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.


Solution

  • 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])