Search code examples
c#entity-frameworkef-model-first

Get Entity Framework Model first Entity Name dynamic


I want to do something like this : Get Column name of an Entity in Entity Framework.

I don't want directly using Entity Name , I want to pass Entity-Name to method as string.

 public HttpResponseMessage GetColumnName(string MyClassName)
{

    var db = new DAL.MyEntities();
    var names = typeof(db.MyClassName).GetProperties()
    .Select(property => property.Name)
    .ToArray();

    return new HttpRequestMessage().CreateResponse(HttpStatusCode.OK, names, new HttpConfiguration().Formatters.JsonFormatter);

}

Note : I don't want to use switch-case or If-else .

Why I need this ? I have to return data in an API as JSON . We created a method that convert Entity Models to our class without any relation :

Entity Class:

public partial class foo
{
    public foo()
    {
        this.parent = new HashSet<parent>();
        this.child = new HashSet<child>();
    }

    public int id { get; set; }
    public string title { get; set; }

    public virtual ICollection<parent> parent { get; set; }
    public virtual ICollection<child> child { get; set; }

}

I want to call this API:

public HttpResponseMessage GetFooData()
{
    var db = new DAL.MyEntities();
    var data = db.foos.ToList();
    return new HttpRequestMessage().CreateResponse(HttpStatusCode.OK, data, new HttpConfiguration().Formatters.JsonFormatter);
}

If I Return a List<foo> data will got this error :

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.

to resolve this I have to create another model same as Entity model without any child and parent like this :

public partial class Myfoo
{
    public int id { get; set; }
    public string title { get; set; }

}

Then I will loop on List<foo> and fill List<Myfoo> , then I will return List<Myfoo>.

Now creating this class wasting my time every day and I want to create a Generator that create MyFoo and Generator to fill Lis<MyFoo> with List<Foo> .


Solution

  • My problem resolved as shown below :

    public List<string> GetServiceModelProprty(string EntityName, bool ShowGeneric = false)
        {
    
            List<string> ProNames = new List<string>();
            var names = Type.GetType(EntityName)
                .GetProperties()
                .Select(p => p.Name).ToArray();
            ProNames.AddRange(names);
            return ProNames;
        }
    

    I get all property from Entity , note that EntityName should contain NameSpace like : DAL.MyClassName

    Also this is my mapper Generator :

    public class MapperGenerator
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="FullEntityName">Entity Name in  DataBase Contain NameSpace</param>
        /// <param name="ServiceModelName"></param>
        /// <param name="MapperFunctionName"></param>
        /// <param name="NeedHtmlBreak"></param>
        /// <returns></returns>
        public string GenerateMapperString(string FullEntityName, string ServiceModelName, string MapperFunctionName, bool NeedHtmlBreak)
        {
    
            List<string> PropNames = new List<string>();
            var names = new ECBVendorDAL.DataMapperGenerator().GetServiceModelProprty(FullEntityName);
            PropNames.AddRange(names);
            // DB Entity
            string EntityName = FullEntityName.Split('.')[1];
            //Service Model
            string B_SM = ServiceModelName;
            // Function In Mapper
            string strFunc = MapperFunctionName;
    
            StringBuilder sb = new StringBuilder();
            // A>B
            sb.Append(GetModelString(PropNames, EntityName, ServiceModelName, strFunc, NeedHtmlBreak, false));
            // B>A
            sb.Append(GetModelString(PropNames, ServiceModelName, EntityName, strFunc, NeedHtmlBreak, false));
            //List<A> to List<B>
            sb.Append(GetModelString(PropNames, EntityName, ServiceModelName, strFunc, NeedHtmlBreak, true));
            //List<B> to List<A>
            sb.Append(GetModelString(PropNames, ServiceModelName, EntityName, strFunc, NeedHtmlBreak, true));
    
            return sb.ToString();
        }
    
        private string GetModelString(List<string> ColunNames, string ReturnedClass, string PassedClass, string strFunctionName, bool ApplyHtmlBr, bool IsList = false)
        {
            string htmlBr = ApplyHtmlBr ? "<br />" : string.Empty;
            StringBuilder Sb = new StringBuilder();
            if (IsList)
            {
                #region dbModelName To dbServiceModelName
                //public static List<VendorServiceModel> GetVendorServiceModel(ICollection<ECB_Vendor> input)
                Sb.Append("<xmp>");
                Sb.Append(string.Format("public static List<{0}> {2}(ICollection<{1}> input)", ReturnedClass, PassedClass, strFunctionName));
                Sb.Append("</xmp>" + htmlBr);
                Sb.Append("{" + htmlBr);
                // -    -   -   -   - List<VendorServiceModel> result = new List<VendorServiceModel>();
                Sb.Append("<xmp>");
                Sb.Append(string.Format(" List<{0}> result = new List<{0}>();", ReturnedClass));
                Sb.Append("</xmp>" + htmlBr);
                Sb.Append("foreach (var item in input)" + htmlBr);
                Sb.Append("{" + htmlBr);
                Sb.Append("<xmp>");
                Sb.Append(string.Format("result.Add({0}(item));", strFunctionName));
                Sb.Append("</xmp>" + htmlBr);
                Sb.Append("}" + htmlBr);
                Sb.Append("return result;" + htmlBr);
                Sb.Append("}" + htmlBr);
                #endregion
            }
            else
            {
                #region One - PassedClass To ReturnedClass
    
                Sb.Append(htmlBr);
                Sb.Append(string.Format("public static {0} {2}({1} input)" + htmlBr, ReturnedClass, PassedClass, strFunctionName));
                Sb.Append("{" + htmlBr);
                Sb.Append(string.Format("return new {0}()", ReturnedClass));
                Sb.Append("{" + htmlBr);
                foreach (var item in ColunNames)
                {
                    Sb.Append(string.Format("{0} = input.{0} , " + htmlBr, item));
                }
                Sb.Append("};" + htmlBr);
                Sb.Append("}" + htmlBr);
                Sb.Append(htmlBr);
    
                #endregion
    
            }
    
            return Sb.ToString();
    
        }
    
    }