Click here to Skip to main content
15,887,331 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have this code for generating a class.

namespace EFCodeFirstTest
{
    class GenClass
    {
        CodeCompileUnit CompileUnit;
        CodeTypeDeclaration NewClass;

        public GenClass(String Classname)
        {
            CompileUnit = new CodeCompileUnit();
            CodeNamespace ns = new CodeNamespace("EFCodeFirstTest");
            ns.Imports.Add(new CodeNamespaceImport("System"));
            ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
            ns.Imports.Add(new CodeNamespaceImport("System.ComponentModel.DataAnnotations"));
            ns.Imports.Add(new CodeNamespaceImport("System.ComponentModel.DataAnnotations.Schema"));
            ns.Imports.Add(new CodeNamespaceImport("System.Data.Entity.Spatial"));
            NewClass = new CodeTypeDeclaration(Classname);
            NewClass.IsClass = true;
            NewClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
            ns.Types.Add(NewClass);
            CompileUnit.Namespaces.Add(ns);
        }

        public void AddColumns()
        {
            CodeMemberField mfield0 = new CodeMemberField(typeof(Int32), "RefNo");
            mfield0.Attributes = MemberAttributes.Public;
            mfield0.Type = new CodeTypeReference(typeof(Int32));
            NewClass.Members.Add(mfield0);
        }

        public void CreateCS(String mfilename)
        {
            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
            CodeGeneratorOptions options = new CodeGeneratorOptions();
            options.BracingStyle = "C";
            options.BlankLinesBetweenMembers = false;
            using (StreamWriter sw = new StreamWriter(mfilename))
            {
                provider.GenerateCodeFromCompileUnit(CompileUnit, sw, options);
            }
        }
    }
}



I call it like this :

GenClass objGenClass = new GenClass("Folio2");
objGenClass.AddColumns();
objGenClass.CreateCS(@"../../Models/Folio2.cs");


It has generated this code :

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace EFCodeFirstTest
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;
    
    public sealed class Folio2
    {
        public int RefNo;
    }
}




How can I add the [Key] attribute above the field and also how to designate the field as IDENTITY ?

Im looking for this output :

[Key]
public int Refno {get; set;}

Please suggest. Thank you in advance.

What I have tried:

Tried doing it as in this Link but it is not working for Primary key attribute.

Tried adding the KeyAttribute through CustomAttributes.Add. Didn't work.

Also Tried :

CodeAttributeDeclaration mattr = new CodeAttributeDeclaration("Key");
CodeMemberField mfield0 = new CodeMemberField(typeof(Int32), "RefNo");
mfield0.CustomAttributes.Add(mattr);


It resulted in :

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace EFCodeFirstTest
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;
    
    public sealed class Folio2
    {
        [Key()]
        public int RefNo;
    }
}
Posted
Updated 16-Jan-19 2:23am
v3
Comments
Maciej Los 16-Jan-19 8:02am    
As far as i remember, if you replace RefNo with ID, EF will treat this field as a [Key].
Priya-Kiko 16-Jan-19 11:46am    
Thank you for the response. Tried changing the column name to ID, yet no luck !!

1 solution

Seems you need to add a reference to: System.ComponentModel.DataAnnotations, then add a CodeAttributeDeclaration. See:

C#
var attr = new CodeAttributeDeclaration(new CodeTypeReference(typeof(System.ComponentModel.DataAnnotations.KeyAttribute)));


Source:
Add attribute using Codedom in C# - Stack Overflow[^]
c# - Add data annotations to a class generated by entity framework - Stack Overflow[^]
KeyAttribute Class (System.ComponentModel.DataAnnotations) | Microsoft Docs[^]

Note: not tested!
 
Share this answer
 
Comments
Priya-Kiko 16-Jan-19 11:44am    
Thank you for the response @Maciej Los. I tried with the code you suggested. But the output is kind of like this :

namespace EFCodeFirstTest
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;

public sealed class Folio2
{
[System.ComponentModel.DataAnnotations.KeyAttribute()]
public int RefNo;
}
}

Will this provide the [Key] functionality ?
Maciej Los 16-Jan-19 11:49am    
Check it out.
Priya-Kiko 16-Jan-19 12:12pm    
No ! EF does not recognize that as a Primary Key. I got this error during migration.

EFCodeFirstTest.RuntimeType: : EntityType 'RuntimeType' has no key defined. Define the key for this EntityType.
Maciej Los 16-Jan-19 12:20pm    
So, try to use: new CodeTypeReference(typeof("[Key]"))
I'm new to this, so...
Priya-Kiko 16-Jan-19 23:27pm    
ok.. no problem... That will not work.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900