Entity Framework: Get the DataType of Metadata IProperty

喜欢而已 提交于 2020-12-15 06:14:49

问题


How do I find the DataType of Metadata.IProperty in Entity Framework Core?

var tableType = _dbContext.Model.GetEntityTypes().First(c => c.GetTableName() == tableName);
foreach (var property in tableType.GetProperties())
{
     var test = property.PropertyInfo.PropertyType.Name;

Using property.PropertyInfo.PropertyType.Name, sometimes works, however for nullable objects it prints null. I am looking for a clean way to get data type.


回答1:


The Type of the IProperty is represented by ClrType property. It handles correctly both real properties (having PropertyInfo), fields (EF Core 5.0+ allow mapping fields as properties), and also shadow properties which have no assocaited PropertyInfo or FieldInfo at all.

var tableType = _dbContext.Model.GetEntityTypes().First(c => c.GetTableName() == tableName);
foreach (var property in tableType.GetProperties())
{
    Type type = property.ClrType;
}

Now speaking about string representation of that Type, it is arbitrary (similar any formatting) and depends on your needs. For instance, for debug display purposes EF Core internally uses the ShortDisplayName method. You can eventually use it, but note that it uses C# built-in types (e.g. int instead of Int32) and formats nullable type as "Nullable<{TypeName}>" e.g.

Requires

using Microsoft.EntityFrameworkCore.Infrastructure;

and then

var tableType = _dbContext.Model.GetEntityTypes().First(c => c.GetTableName() == tableName);
foreach (var property in tableType.GetProperties())
{
    var type = property.ClrType;
    var typeName = type.ShortDisplayName();
}

Again, converting Type to string differs, and depends on what this string will be used for. So use Type instead of string where possible. GetColumnType is different - it returns string because there is no class similar to Type to represent the database provider types.




回答2:


You may look for this:Get PropertyType.Name in reflection from Nullable type

var propertyType = propertyInfo.PropertyType;

if (propertyType.IsGenericType &&
        propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
      propertyType = propertyType.GetGenericArguments()[0];
    }

model.ModelProperties.Add(new KeyValuePair<Type, string>
                        (propertyType.Name,propertyInfo.Name));



回答3:


Since you are already using PropertyType.Name, I'm assuming that you are expecting a string denoting the name of the types, and not more information about the types.

  1. You can use IProperty.ClrType to get the data type of an IProperty
  2. You can detect nullability of a type with Nullable.GetUnderlyingType()
  3. Nullable types are basically generic types, Nullable<T>, so you can obtain the type arguments with Type.GenericTypeArguments property

Combining the facts above you can create an extension method like -

public static string GetPropertyType(this IProperty property)
{
    return Nullable.GetUnderlyingType(property.ClrType) != null
        ? nameof(Nullable) + "<" + property.ClrType.GenericTypeArguments.First().Name + ">"
        : property.PropertyInfo.PropertyType.Name;
}

Now, nullable or not, you can get a "clean" string for the data type name -

var tableType = _dbContext.Model.GetEntityTypes().First(c => c.GetTableName() == tableName);
foreach (var property in tableType.GetProperties())
{
     var test = property.GetPropertyType();
}


来源:https://stackoverflow.com/questions/65031605/entity-framework-get-the-datatype-of-metadata-iproperty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!