【问题标题】:linq2db specify custom conversions for fields going to / from the database to convert to/from specific C# typeslinq2db 为去往/来自数据库的字段指定自定义转换以转换为/来自特定 C# 类型
【发布时间】:2016-01-11 18:38:21
【问题描述】:

在我们必须使用的数据库(即 DB2)中,有些字段存储为字符,但实际上是其他对象,最常见的是底层应用程序存储日期和时间的自定义方式。例如:

[Table]
public class ExampleTable {
    // This is stored in the DB as a char in the format: 2016-01-11-11.39.53.492000
    [Column(Name = "WTIMESTAMP")] public string WriteTimestamp { get; set; }
}

有没有办法告诉 linq2db 在从数据库转换到/从数据库时使用的转换方法,这也将允许我们将这些属性作为我们想要的对象(例如,C# DateTime 对象)来访问,但是得到以正确的格式保存回来?

我想到的一件事是这样的:

[Table]
public class ExampleTable {

    public DateTime WriteTimestamp { get; set; }

    // This is stored in the DB as a char in the format: 2016-01-11-11.39.53.492000
    [Column(Name = "WTIMESTAMP")] public string WriteTimestampRaw 
    { 
        get {
            return ConvertWriteTimestampToDb2Format(WriteTimestamp);
        } 
        set {
            WriteTimestamp = ConvertWriteTimestampToDateTime(value);    
        }
    }
}

然后我们访问 WriteTimestamp,但 linq2db 在查询中使用 WriteTimestampRaw。

但是,我不确定这是最好的选择还是唯一的选择。提前致谢。

【问题讨论】:

  • DB2 中的实际数据类型是(VAR)CHAR 吗?如果它是TIMESTAMP 类型,如果您使用 DateTime 数据类型,.net 应该能够对其进行转换。
  • @bhamby 不幸的是,它是 CCID 为 37 的字符类型。还有其他几个类似的东西。例如,在另一个地方,它们只存储儒略日期格式的日期(YYYYDDD,其中 DDD 是一年中的某一天),实际上是以十进制格式存储的。
  • inq2db 3.0.0-rc1 计划于本周发布,增加了使用值转换器 github.com/linq2db/linq2db/wiki/… 的每列转换配置支持

标签: c# db2 linq2db


【解决方案1】:

嗯...在我发布答案后,我注意到您说的是 linq2db 而不是实体框架。不过,也许它仍然会给你一些想法。


我之前对 Entity Framework 所做的(虽然不是专门针对 DB2,但我认为它应该仍然可以工作),是使用提供的代码 in this answer 允许将私有属性映射到数据库列。然后,我有一些类似于你的代码的东西,除了 getter 和 setter 是相反的:

[Table("ExampleTable")]
public class ExampleTable
{
    [NotMapped]
    public DateTime WriteTimestamp
    {
        get
        {
            var db2Tstamp = DB2TimeStamp.Parse(WriteTimestampRaw);
            return db2Tstamp.Value;
        }
        set
        {
            var db2Tstamp = new DB2TimeStamp(value);
            WriteTimestampRaw = db2Tstamp.ToString();
        }
    }

    // This is stored in the DB as a char in the format: 2016-01-11-11.39.53.492000
    [Column("WTIMESTAMP")]
    private string WriteTimestampRaw { get; set; }
}

我使用DB2TimeStamp class 来处理字符串和 DateTime 值之间的转换,但是您可以随意进行操作。

【讨论】:

  • 我认为这样的事情会奏效。我颠倒了我的getter/setter的主要原因是因为我认为如果数据库设置了私有WriteTimestampRaw,然后设置了公共WriteTimestamp,这意味着它只转换来自数据库的那个,然后再一次回去。就像你所拥有的那样反转(iirc)每次调用都将其转换为WriteTimestamp。我看的越多,我就越想这就是我要走的路。谢谢! (编辑:此外,这个概念也应该从 EF 延续到这个。)
  • @ThomasF。想了一会儿,我想我喜欢你的方法胜过我自己的方法。在我看来,访问代码中的属性可能比写入/写入数据库更多。我必须尝试一些测试才能看到差异!
  • 了解这些差异会很有趣。虽然我不会说这个应用程序会受到重创,但它会有一些流量。我不知道你的实现和我的实现之间的差异是否足以产生很大的影响,但仍然如此。我目前唯一不喜欢的是 linq2db 不能对私有属性做任何事情:/ 无论如何,很想听听你的想法!
【解决方案2】:

您可以使用 MappingSchema.SetConverter 方法在客户端设置特定类型之间的转换。或 MappingSchema.SetConverterExpression 将转换器创建为查询树的一部分。

【讨论】:

  • 谢谢,我明天进办公室看看这个。您是否碰巧有一个小代码块来演示它,或者我可以参考的文档?编辑:基本上我不确定它在哪里使用,仅此而已。
  • 谢谢!没想到看测试。我明天去看看
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-17
  • 2016-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
相关资源
最近更新 更多