问题
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.
- You can use
IProperty.ClrType
to get the data type of anIProperty
- You can detect nullability of a type with
Nullable.GetUnderlyingType()
- 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