如何使用Entity Framework Core配置其他用户定义的数据类型? [英] How do I configure other user defined data-type with Entity Framework Core?
问题描述
我在Entiy Framework Core 2.1中使用了支架式实体。第三方数据库使用一些未定义的数据类型()似乎没有被EF-Core识别。
I'm using scaffolded entities with Entiy Framework Core 2.1. The 3rd party database uses some unser defined data types (that I didn't know about) that don't seem to be recognized by EF-Core.
根据到 Fluent API HasColumnType方法和反向引擎:支持类型别名(用户定义的数据类型),这应该可以工作。但是,我不确定是否仅适用于预先修饰的/内置的类型,例如 Name
或任何类型。
According to The Fluent API HasColumnType Method and Reverse Enginer: Support type aliases (user-defined data types) this should work. However, I'm not sure if only for precofigured/built-in types like Name
or any types.
引擎会生成该
entity.Property(e => e.Status).HasColumnType("Enumeration");
用于 Enumeration:smallint
,但将其翻译为SQL无法正常运行,因此会引发 SqlException
for Enumeration:smallint
but translating it to SQL doesn't work well so it throws a SqlException
Class 16 byte
LineNumber 1 int
Message "Type Enumeration is not a defined system type." string
Number 243 int
Procedure "" string
Server "..." string
Source ".Net SqlClient Data Provider" string
State 2 byte
是否可以定义其他用户定义的数据类型或将其修复为
Is there a way to define other user defined data types or fix this in any other way?
推荐答案
我找到了一种解决方法。
I've found a workaround.
在 OnModelCreating
方法的和,我将删除生成的 ColumnType
注释:
At the and of the OnModelCreating
method I'll just remove the generated ColumnType
annotation:
modelBuilder
.Entity(typeof(MyEntity))
.Property(nameof(MyEntity.Status))
.Metadata
.RemoveAnnotation("Relational:ColumnType");
一个小的帮助程序函数,它遍历所有实体并自动从具有该属性的所有属性中删除该注释
A small helper function that goes over all entities and removes that annotation automatically from all properties that have it should be enough for now.
public static class ModelBuilderExtensions
{
public static ModelBuilder RemoveAnnotations<TDbContext>(this ModelBuilder modelBuilder, TDbContext context, string name, IList<string> values) where TDbContext : DbContext
{
var bindingFlags =
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.DeclaredOnly;
var entityMethod =
typeof(ModelBuilder)
.GetMethods()
.Single(m =>
m.Name == nameof(ModelBuilder.Entity) &&
m.GetGenericArguments().Length == 1 &&
m.GetParameters().Length == 0
)
.GetGenericMethodDefinition();
foreach (var contextProperty in typeof(TDbContext).GetProperties(bindingFlags))
{
var entity =
contextProperty
.PropertyType
.GetGenericArguments()
.SingleOrDefault();
if (entity is null)
{
continue;
}
// Only the generic overload returns properties. The non-generic one didn't work.
var generitcEntityMethod = entityMethod.MakeGenericMethod(entity);
foreach (var property in entity.GetProperties(bindingFlags))
{
var entityTypeBuilder = (EntityTypeBuilder)generitcEntityMethod.Invoke(modelBuilder, null);
if (entityTypeBuilder.Metadata.FindProperty(property) is null)
{
continue;
}
var annotation =
entityTypeBuilder
.Property(property.Name)
.Metadata
.FindAnnotation(name);
if (values.Contains(annotation?.Value))
{
entityTypeBuilder
.Property(property.Name)
.Metadata
.RemoveAnnotation(name);
}
}
}
return modelBuilder;
}
}
用法:
modelBuilder.RemoveAnnotations(this, "Relational:ColumnType", new[] { "Enumeration" });
这篇关于如何使用Entity Framework Core配置其他用户定义的数据类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!