【问题标题】:Generic UTC DateTime serialization in Apache IgniteApache Ignite 中的通用 UTC DateTime 序列化
【发布时间】:2020-09-18 12:49:48
【问题描述】:

我正在使用 Ignite .NET 瘦客户端。

在 ignite 文档中写道,为了支持平台互操作性,我们应该以 UTC 格式存储 DateTime。我还可以以本地格式存储 DateTime 值,但在这种情况下无法在 DBeaver 中查看数据。 当我将数据放入缓存或从缓存中获取数据时,我必须手动将 DateTime 值从 UTC 或本地格式转换。对于转换,我使用 DateTime.SpecifiyKind 或 DateTime.ToUniverslaTime、DateTime.ToLocalTime 方法,如下例所示。 是否有任何通用解决方案可以在 UTC 和本地格式之间自动转换所有 DateTime 值,而不是为应用程序中每个模型的每个属性编写自定义逻辑? 也许它可能是某种通用的 DateTime 序列化器。

public class Person
{
    public string FirstName { get; set; }
    public DateTime Birthday { get; set; }
}

[STAThread]
public static void Main()
{
    var configuration = new Core.Client.IgniteClientConfiguration
    {
        Endpoints = new List<string> { "127.0.0.1" },
        BinaryConfiguration = new BinaryConfiguration
        {
            Serializer = new BinaryReflectiveSerializer { ForceTimestamp = true }
        }
    };

    using (var ignite = Ignition.StartClient(configuration))
    {
        var person = new Person { FirstName = "John", Birthday = new DateTime(1990, 08, 17) };

        var cacheConfiguration = new CacheClientConfiguration("people", new QueryEntity(typeof(int), typeof(Person)));

        //person.Birthday = person.Birthday.ToUniversalTime();
        person.Birthday = DateTime.SpecifyKind(person.Birthday, DateTimeKind.Utc);
                
        var cache = ignite.GetOrCreateCache<int, Person>(cacheConfiguration);
                
        cache.Put(0, person);

        var personFromCache = cache.AsCacheQueryable().Select(x => x.Value).FirstOrDefault();

        //personFromCache.Birthday = personFromCache.Birthday.ToLocalTime();
        personFromCache.Birthday = DateTime.SpecifyKind(personFromCache.Birthday, DateTimeKind.Local);
    }
}

【问题讨论】:

    标签: c# .net ignite


    【解决方案1】:

    Ignite 不提供这种自动转换。一些选项是:

    • 实现IBinarizable 接口并在那里执行转换:
        public class Person2 : IBinarizable
        {
            public DateTime Date { get; set; }
    
            public void WriteBinary(IBinaryWriter writer)
            {
                writer.WriteTimestamp("Date", Date.ToUniversalTime());
            }
    
            public void ReadBinary(IBinaryReader reader)
            {
                Date = reader.ReadTimestamp("Date").Value.ToLocalTime();
            }
        }
    
    
    • 使用序列化属性挂钩进程:
        [Serializable]
        public class Person
        {
            public DateTime Date { get; set; }
            
            [OnSerializing]
            internal void OnSerializingMethod(StreamingContext context)
            {
                Date = Date.ToUniversalTime();
                Console.WriteLine("OnSerializing");
            }
    
            [OnSerialized]
            internal void OnSerializedMethod(StreamingContext context)
            {
                Date = Date.ToLocalTime();
                Console.WriteLine("OnSerialized");
            }
    
            [OnDeserialized]
            internal void OnDeserializedMethod(StreamingContext context)
            {
                Date = Date.ToLocalTime();
                Console.WriteLine("OnDeserialized");
            }
        }
    
    • 使用带有支持字段的属性并在 getter 和 setter 中执行转换

    不过,所有这些都需要对每个属性进行单独处理 - 如果没有反射和/或代码生成,我没有更好的想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多