0

I can't understand why my fieldType is not qualified as a generic list. I tried to use the solution proposed below to get the generic type of a list. But when I reach fieldType.IsGenericType == false, I was quite surprised and I don't understand what is happening.

My goal is to be able to use my method CreateTable() for each field in my context. My context should only have List fields.

This is the information i found in my object:

FieldType = {Name = "List`1" FullName = 
"System.Collections.Generic.List`1[[WebApplication1.Models.Movie, WebApplication1,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}

Reference : C# generic list <T> how to get the type of T?

My code example:

public class MediaContext
{
    public List<Movie> Movies { get; set; }
    public List<Subtitle> Subtitles { get; set; }

    public MediaContext()
    {
        this.Movies = new List<Movie>();
        this.Subtitles = new List<Subtitle>();
    }
}


public void CreateDB(object context)
{
    Type type = context.GetType();
    FieldInfo[] fields = type.GetFields(BindingFlags.Instance 
        | BindingFlags.NonPublic);

    foreach (FieldInfo field in fields)
    {
        Type genericType = this.GetGenericType(field);

        MethodInfo method = this.GetType().GetMethod("CreateTable");
        MethodInfo generic = method.MakeGenericMethod(genericType);
        generic.Invoke(this, null);
    }

    foreach (FieldInfo field in fields)
    {
        Type genericType = this.GetGenericType(field);

        MethodInfo method = this.GetType().GetMethod("AddKeys");
        MethodInfo generic = method.MakeGenericMethod(genericType);
        generic.Invoke(this, null);
    }
}

private Type GetGenericType(FieldInfo field)
{
    Type fieldType = field.GetType();
    Type genericType = null;
    // Where I believe is should be generic.
    if (fieldType.IsGenericType && 
        fieldType.GetGenericTypeDefinition() == typeof(List<>))
    {
        genericType = fieldType.GetGenericArguments()[0];
    }
    else
    {
        throw new Exception("An array is needed");
    }

    return genericType;
}

public void CreateTable<T>()
{
    StringBuilder query = new StringBuilder();
    Type type = typeof(T);

    query.Append(String.Format("CREATE TABLE {0} (", NamingGeneration.PlurializeName(type.Name)));

    query.Append(this.AddFields(typeof(T).GetProperties()));

    query.Append(")");

    SqlCommand command = new SqlCommand();

    command.CommandText = query.ToString();

    SqlExecuteRequest.Instance.ExecuteNonQuery(command);
}

private void AddKeys<T>()
{
    Type type = typeof(T);
    PropertyInfo[] properties = type.GetProperties();

    IEnumerable<PropertyInfo> keyedProperties = properties.Where(x => x.Name.Contains("Id"));

    foreach (PropertyInfo property in keyedProperties)
    {
        if (property.Name == "Id")
        {
            this.AddPrimaryKey(type.Name, property.Name);
        }
        else if (property.Name.EndsWith("Id"))
        {
            this.AddForeignKey(type.Name, property.Name);
        }
    }
}
Community
  • 1
  • 1
Kadgiko
  • 355
  • 3
  • 14
  • Can you tell us a little more about the actual problem you're trying to solve? Most of the time, you're not going to need this information to write usable generic code. – Robert Harvey Sep 09 '14 at 19:17
  • 4
    You haven't shown either of the methods that you're reflecting on. – Servy Sep 09 '14 at 19:17
  • My goal is to be able to use my method CreateTable() for each field in my context. My context should only have List fields. – Kadgiko Sep 09 '14 at 19:27

1 Answers1

5

To fix the code as you have it, instead of

   Type fieldType = field.GetType();

You want

Type fieldType = field.FieldType;

And it will work. FieldInfo is what you pass through. When you call GetType(), the type you're getting is the FieldInfo type information. FieldInfo contains information about a Field, and the Type information is held in FieldInfo.FieldType.

If you step through this code, you would see this behavior. Debugging is useful.

tbddeveloper
  • 2,407
  • 1
  • 23
  • 39