Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Entity Framework Core配置其他用户定义的数据类型?_C#_Tsql_Entity Framework Core_Sql Server 2014 - Fatal编程技术网

C# 如何使用Entity Framework Core配置其他用户定义的数据类型?

C# 如何使用Entity Framework Core配置其他用户定义的数据类型?,c#,tsql,entity-framework-core,sql-server-2014,C#,Tsql,Entity Framework Core,Sql Server 2014,我正在使用EntiFrameworkCore2.1中的脚手架实体。第三方数据库使用一些unser定义的数据类型(),EF Core似乎无法识别这些数据类型 根据这一点,这应该是可行的。但是,我不确定是否只针对预配置/内置类型,如Name或任何类型 发动机会产生这种情况 entity.Property(e => e.Status).HasColumnType("Enumeration"); 对于枚举:smallint,但将其转换为SQL效果不好,因此会抛出SqlException 有没有一

我正在使用EntiFrameworkCore2.1中的脚手架实体。第三方数据库使用一些unser定义的数据类型(),EF Core似乎无法识别这些数据类型

根据这一点,这应该是可行的。但是,我不确定是否只针对预配置/内置类型,如
Name
或任何类型

发动机会产生这种情况

entity.Property(e => e.Status).HasColumnType("Enumeration");
对于
枚举:smallint
,但将其转换为SQL效果不好,因此会抛出
SqlException


有没有一种方法可以定义其他用户定义的数据类型或以任何其他方式修复此问题?

我找到了一种解决方法

OnModelCreating
方法的和处,我将删除生成的
ColumnType
注释:

  modelBuilder
    .Entity(typeof(MyEntity))
    .Property(nameof(MyEntity.Status))
    .Metadata
    .RemoveAnnotation("Relational:ColumnType");
一个覆盖所有实体并自动从所有具有注释的属性中删除注释的小辅助函数现在应该足够了

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;
    }
}

您可能想了解这一点。此外,类型别名(又名域)与用户定义类型(UDT)非常不同。@bricelam谢谢!我们怀疑这也是UDT。不幸的是,这些在.NETCore上的支持有限…@bricelam来看看。有一个变通办法。
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" });