Thanks Pavel, it works brilliantly!

Here’s my code right now, and it is working nicely:

private BinaryConfiguration CreateBinaryConfiguration()
        {
            var binaryReflectiveSerializer = new BinaryReflectiveSerializer
                                                 {
                                                     ForceTimestamp = true
                                                 };

            var binaryTypeConfigurations = new List<BinaryTypeConfiguration>();
            foreach (var type in CacheConstant.GetDomainEntities())
            {
                var binaryTypeConfiguration = new BinaryTypeConfiguration(type)
                                                  {
                                                      Serializer = 
binaryReflectiveSerializer
                                                  };
                binaryTypeConfigurations.Add(binaryTypeConfiguration);
            }

            return new BinaryConfiguration
                       {
                           TypeConfigurations = binaryTypeConfigurations
                       };
        }


private ICollection<CacheConfiguration> CreateCacheConfigCollection()
        {
            var cacheConfigs = new List<CacheConfiguration>();

            foreach (var mapping in CacheConstant.GetDomainEntities())
            {
                MethodInfo method = 
typeof(CacheServerInitializer).GetMethod("CreateCacheConfig", 
BindingFlags.NonPublic | BindingFlags.Instance);
                MethodInfo generic = method.MakeGenericMethod(mapping.Key);
                var cacheConfig = (CacheConfiguration)generic.Invoke(this, 
null);
                cacheConfigs.Add(cacheConfig);
            }

            return cacheConfigs;
        }

        private CacheConfiguration CreateCacheConfig<T>()
            where T : DomainEntity
        {
            var type = typeof(T);
            var cacheName = CacheConstant.GetCacheName<T>();

            var queryFields = new List<QueryField>();
            foreach (var property in type.GetProperties())
            {
                var queryField = new QueryField(property.Name, 
property.PropertyType)
                                     {
                                         IsKeyField = property.Name == "Id"
                                     };
                queryFields.Add(queryField);
            }

            var queryEntity = new QueryEntity
                                  {
                                      KeyType = typeof(long),
                                      ValueType = type,
                                      Fields = queryFields.ToArray()
                                  };

            return new CacheConfiguration
                       {
                           Name = cacheName,
                           QueryEntities = new[] { queryEntity },
                           CacheMode = CacheMode.Replicated,
                           CacheStoreFactory = 
this.cacheStoreFactory.CreateCacheStoreFactory<T>(),
                           ReadThrough = true,
                           WriteThrough = true,
                           KeepBinaryInStore = false
                       };
        }


Thanks,
Narayana.

From: Pavel Tupitsyn [mailto:[email protected]]
Sent: 07 July 2017 18:57
To: [email protected]
Subject: Re: Dymanically add QueryField on Cache Entity and perform DateTime 
filter.

This can be tested with a nightly build right now: 
https://cwiki.apache.org/confluence/display/IGNITE/Nightly+Builds

> Install-Package Apache.Ignite -Pre -Source 
> https://www.myget.org/F/apache-ignite-net-nightly

On Fri, Jul 7, 2017 at 4:26 PM, Pavel Tupitsyn 
<[email protected]<mailto:[email protected]>> wrote:
Addition:

In upcoming 2.1 version there is a BinaryReflectiveSerializer.ForceTimestamp 
property, which makes it write any DateTime as a Timestamp.
So instead of a custom serializer, you can do this:

BinaryConfiguration = new BinaryConfiguration
                {
                        TypeConfigurations = new[] { new 
BinaryTypeConfiguration(typeof(ABC)) {
Serializer = new BinaryReflectiveSerializer {ForceTimestamp = true} }}
                }

On Wed, Jul 5, 2017 at 11:44 AM, ptupitsyn 
<[email protected]<mailto:[email protected]>> wrote:
Hi,

Please properly subscribe to the mailing list so that the community can
receive email notifications for your messages. To subscribe, send empty
email to 
[email protected]<mailto:[email protected]> and 
follow simple instructions in
the reply.

I have reproduced the problem, it is caused by the fact that DateTime is
serialized in .NET-specific format by default, and this does not work in
SQL, see "DateTime and SQL" section:
https://apacheignite-net.readme.io/docs/sql-queries#section-java-type-name-mapping

To enforce SQL-compatible TimeStamp format:
1) Mark the field with [QuerySqlField]. Looks like this is not an option for
you, though, since reflection is used

2) Implement IBinarizable:

public class ABC : IBinarizable
{
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime StartTime { get; set; }

        public void WriteBinary(IBinaryWriter writer)
        {
                writer.WriteInt("Id", Id);
                writer.WriteString("Name", Name);
                writer.WriteTimestamp("StartTime", StartTime);
        }

        public void ReadBinary(IBinaryReader reader)
        {
                Id = reader.ReadInt("Id");
                Name = reader.ReadString("Name");
                StartTime = 
reader.ReadTimestamp("StartTime").GetValueOrDefault();
        }
}

3) Implement IBinarySerializer:

public class AbcSerializer : IBinarySerializer
{
        public void WriteBinary(object o, IBinaryWriter writer)
        {
                var abc = (ABC)o;

                writer.WriteInt("Id", abc.Id);
                writer.WriteString("Name", abc.Name);
                writer.WriteTimestamp("StartTime", abc.StartTime);
        }

        public void ReadBinary(object o, IBinaryReader reader)
        {
                var abc = (ABC)o;

                abc.Id = reader.ReadInt("Id");
                abc.Name = reader.ReadString("Name");
                abc.StartTime = 
reader.ReadTimestamp("StartTime").GetValueOrDefault();
        }
}

and register it in config:
                BinaryConfiguration = new BinaryConfiguration
                {
                        TypeConfigurations = new[] { new 
BinaryTypeConfiguration(typeof(ABC)) {
Serializer = new AbcSerializer() }}
                }




--
View this message in context: 
http://apache-ignite-users.70518.x6.nabble.com/Dymanically-add-QueryField-on-Cache-Entity-and-perform-DateTime-filter-tp14318p14319.html
Sent from the Apache Ignite Users mailing list archive at Nabble.com.


Reply via email to