动态类型转换实体框架 ORM

Posted

技术标签:

【中文标题】动态类型转换实体框架 ORM【英文标题】:Dynamic typeConvertion Entity Framework ORM 【发布时间】:2018-02-06 08:27:11 【问题描述】:

您好,我正在处理使用 Telerik ORM 的遗留代码。 基于从后端 db2 迁移的 MSsql 数据库。

据我所知,DB2 不提供用于在表中存储 布尔值 的专用类型。此问题有不同的解决方法。在我的情况下,决定使用 custom Sql type BITTYPE:char(1),它实际上保留了两个不同的 char(1) 值('1' (true)'0' (false))。 Telerik ORM 使用自定义 AdoTypeConverter 将此 char(1) 值转换为域 布尔属性

public class BitTypeToBooleanConverter : TypeConverterBase

    public BitTypeToBooleanConverter()
    
        this.ConverterType = typeof(bool);
        this.NullableConverterType = typeof(bool?);
    

    public override object Read(ref DataHolder holder)
    
        bool n = holder.Reader.IsDBNull(holder.Position);
        holder.NoValue = n;
        if (n)
        
            if (nullable)
                holder.ObjectValue = null;
            else if (holder.Box)
                holder.ObjectValue = false;
            else
                holder.BooleanValue = false;
        
        else
        
            string s = holder.Reader.GetValue(holder.Position).ToString();
            bool outValue = false;
            if (!bool.TryParse(s,out outValue))
            
                if (s.Equals("1"))
                
                    outValue = true;
                
            
            if (nullable || holder.Box)
                holder.ObjectValue = outValue;
            else
                holder.BooleanValue = outValue;
        
        return (holder.Box || nullable) ? holder.ObjectValue : null;
    

    public override void Write(ref DataHolder holder)
    
        holder.Parameter.DbType = System.Data.DbType.String;
        if (holder.NoValue)
        
            holder.Parameter.Size = 1;
            holder.Parameter.Value = null;
        
        else
        
            string s = (holder.BooleanValue ? "1" : "0");
            holder.Parameter.Size = s.Length;
            holder.Parameter.Value = s;
        
    

    public override bool CreateLiteralSql(ref DataHolder holder)
    
        if (holder.NoValue)
        
            holder.StringValue = "NULL";
            return false;
        
        else
        
            holder.StringValue = (holder.BooleanValue ? "1" : "0");
            return true; // inidicating that ' are needed around, because it is a character column (VARCHAR)
        
    

问:我无法更改数据库,但我需要以某种方式教 Entity Framework ORM 在相同的场景下工作

P.s看完文章后(

https://msdn.microsoft.com/en-us/library/jj819164(v=vs.113).aspx),

我尝试使用约定解决此问题,但没有带来结果。

    BITTYPE:char(1) - 错误: 在 SqlServer 提供程序清单中找不到 Char - **错误:**指定的架构无效。错误: (8,12):错误 2019:指定的成员映射无效。 ..

代码sn-p:

     public class BitTypeCharConvention : Convention
        
            private const string DataType = "BITTYPE:char(1)";

            public BitTypeCharConvention()
            
                Properties<bool>().Configure(c => c.HasColumnType(DataType));
            
        

我也知道我可以尝试创建另一个属性来转换字符串的值,但我想要更多 "reusable" 变体

【问题讨论】:

【参考方案1】:

结论:通过,在进行了搜索之后,我实际上还没有找到适合额头解决方案的解决方案。因此决定在数据访问级别保留默认实体框架行为(不进行任何转换),并通过映射(自动映射器)(即实体到域模型)在下一个应用程序级别完成这项工作

【讨论】:

以上是关于动态类型转换实体框架 ORM的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 - 无法将 lambda 表达式转换为类型“字符串”,因为它不是委托类型

将 Json 反序列化为实体框架无法将 int 转换为类型

使用对象角色建模 (ORM) 的关系模型中的动态类型

JPA 简介

创建实体框架核心值转换器:属性“备注”属于“字符串”类型,当前数据库提供程序不支持

动态 SQL 到 LINQ 实体框架