Reputation: 841
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>
.
Upvotes: 0
Views: 956
Reputation: 841
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();
}
}
Upvotes: 0
Reputation: 3373
If you had standard defined DbContext
:
public class MyEntities : DbContext
{
//..
public DbSet<MyEntity> MyEntites { get; set; }
//..
}
you need to use reflection
var db = new DAL.MyEntities();
var type = db.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(pr => pr.PropertyType.IsGenericType)
.Where(pr => pr.PropertyType.GetGenericTypeDefinition() ==
typeof(DbSet<>))
.Select(pr => pr.PropertyType.GetGenericArguments().Single())
.SingleOrDefault(t => t.Name == MyClassName);
if (type == null) / * type not found case */ ;
var names = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Select(property => property.Name)
.ToArray();
Upvotes: 1