Created
November 13, 2017 03:44
-
-
Save ajai8085/364d076e7070c1677d1075467ae720e2 to your computer and use it in GitHub Desktop.
StackExchange.Redis extensions for HashSet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using StackExchange.Redis; | |
namespace RedisPlayground | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var asyncState = new object(); | |
using (var redis = ConnectionMultiplexer.Connect("localhost")) | |
{ | |
var db = redis.GetDatabase(2, asyncState); | |
var customers = GetCustomers().ToList(); | |
var customer6 = customers.FirstOrDefault(i => i.Id == 6); | |
foreach(var cst in customers) | |
{ | |
var propList = cst.ConvertToHashEntryList(); | |
var lst = propList.ToArray(); | |
db.HashSet("user:" + cst.Id, lst); | |
} | |
var hash = db.HashGetAll("user:6").ToList(); | |
var customer6Redis = hash.ConvertFromHashEntryList<Customers>(); | |
if (customer6Redis.Equals(customer6)) | |
{ | |
Console.ForegroundColor = ConsoleColor.Green; | |
Console.WriteLine("Success"); | |
} | |
else | |
{ | |
Console.ForegroundColor= ConsoleColor.DarkRed; | |
Console.WriteLine("Failed"); | |
} | |
Console.ResetColor(); | |
Console.WriteLine("Hello World!"); | |
Console.ReadKey(); | |
} | |
} | |
public static IEnumerable<Customers> GetCustomers() | |
{ | |
return Enumerable.Range(1, 100) | |
.Select(Customers.CreateCustomer); | |
} | |
public class Customers:IEquatable<Customers> | |
{ | |
public Customers() | |
{ | |
} | |
private Customers(int id) | |
{ | |
Id = id; | |
FirstName = "FirstName " + new Random().NextDouble(); | |
LastName= "LastName " + new Random().NextDouble(); | |
Age=new Random().Next(100); | |
CreatedUtc= DateTime.UtcNow; | |
Amount= (decimal)new Random().NextDouble(); | |
Deleted = (new Random().Next() % 2) == 0; | |
Version = Guid.NewGuid().ToString(); | |
CreatedAtLocalNullable= DateTime.Now; | |
CreateAtLocal= DateTime.Now; | |
if (Deleted) | |
{ | |
UpdatedAt= DateTime.Now; | |
} | |
} | |
public static Customers CreateCustomer(int id) | |
{ | |
return new Customers(id); | |
} | |
public int Id { get; set; } | |
public string FirstName { get; set; } | |
public string LastName { get; set; } | |
public DateTime CreatedUtc { get; set; } | |
public DateTime? UpdatedAt { get; set; } | |
public int Age { get; set; } | |
public decimal Amount { get; set; } | |
public bool Deleted { get; set; } | |
public string Version { get; set; } | |
public DateTime? CreatedAtLocalNullable { get; set; } | |
public DateTime CreateAtLocal { get; set; } | |
public bool Equals(Customers other) | |
{ | |
if (ReferenceEquals(null, other)) return false; | |
if (ReferenceEquals(this, other)) return true; | |
return Id == other.Id && string.Equals(FirstName, other.FirstName) && string.Equals(LastName, other.LastName) && CreatedUtc.Equals(other.CreatedUtc) && Age == other.Age && Amount == other.Amount && Deleted == other.Deleted && string.Equals(Version, other.Version); | |
} | |
public override bool Equals(object obj) | |
{ | |
if (ReferenceEquals(null, obj)) return false; | |
if (ReferenceEquals(this, obj)) return true; | |
if (obj.GetType() != this.GetType()) return false; | |
return Equals((Customers) obj); | |
} | |
public override int GetHashCode() | |
{ | |
unchecked | |
{ | |
var hashCode = Id; | |
hashCode = (hashCode * 397) ^ (FirstName != null ? FirstName.GetHashCode() : 0); | |
hashCode = (hashCode * 397) ^ (LastName != null ? LastName.GetHashCode() : 0); | |
hashCode = (hashCode * 397) ^ CreatedUtc.GetHashCode(); | |
hashCode = (hashCode * 397) ^ Age; | |
hashCode = (hashCode * 397) ^ Amount.GetHashCode(); | |
hashCode = (hashCode * 397) ^ Deleted.GetHashCode(); | |
hashCode = (hashCode * 397) ^ (Version != null ? Version.GetHashCode() : 0); | |
return hashCode; | |
} | |
} | |
public static bool operator ==(Customers left, Customers right) | |
{ | |
return Equals(left, right); | |
} | |
public static bool operator !=(Customers left, Customers right) | |
{ | |
return !Equals(left, right); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Runtime.Serialization; | |
using FastMember; | |
namespace StackExchange.Redis | |
{ | |
public static class StackExchangeRedisExtensions | |
{ | |
/// <summary> | |
/// Converts instance of an object to hash entry list. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="instance">The instance.</param> | |
/// <returns></returns> | |
public static IEnumerable<HashEntry> ConvertToHashEntryList<T>(this T instance) where T : new() | |
{ | |
var acessor = TypeAccessor.Create(typeof(T)); | |
var members = acessor.GetMembers(); | |
for(var index = 0; index < members.Count; index++) | |
{ | |
var member = members[index]; | |
if(member.IsDefined(typeof(IgnoreDataMemberAttribute))) | |
{ | |
continue; | |
} | |
var type = member.Type; | |
if (!type.IsValueType)//ATM supports only value types | |
{ | |
if (type != typeof(string)) | |
{ | |
continue; | |
} | |
} | |
var underlyingType = Nullable.GetUnderlyingType(type); | |
var effectiveType = underlyingType ?? type; | |
var val = acessor[instance, member.Name]; | |
if (val != null) | |
{ | |
if (effectiveType == typeof(DateTime)) | |
{ | |
var date = (DateTime) val; | |
if (date.Kind == DateTimeKind.Utc) | |
{ | |
yield return new HashEntry(member.Name, $"{date.Ticks}|UTC"); | |
} | |
else | |
{ | |
yield return new HashEntry(member.Name, $"{date.Ticks}|LOC"); | |
} | |
} | |
else | |
{ | |
yield return new HashEntry(member.Name, val.ToString()); | |
} | |
} | |
} | |
} | |
/// <summary> | |
/// Converts from hash entry list and create instance of type T. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="entries">The entries returned from StackExchange.redis.</param> | |
/// <returns>Instance of Type T </returns> | |
public static T ConvertFromHashEntryList<T>(this IEnumerable<HashEntry> entries) where T : new() | |
{ | |
var acessor = TypeAccessor.Create(typeof(T)); | |
var instance = new T(); | |
var hashEntries = entries as HashEntry[] ?? entries.ToArray(); | |
var members = acessor.GetMembers(); | |
for (var index = 0; index < members.Count; index++) | |
{ | |
var member = members[index]; | |
if (member.IsDefined(typeof(IgnoreDataMemberAttribute))) | |
{ | |
continue; | |
} | |
var type = member.Type; | |
if (!type.IsValueType) //ATM supports only value types | |
{ | |
if (type != typeof(string)) | |
{ | |
continue; | |
} | |
} | |
var underlyingType = Nullable.GetUnderlyingType(type); | |
var effectiveType = underlyingType ?? type; | |
var entry = hashEntries.FirstOrDefault(e => e.Name.ToString().Equals(member.Name)); | |
if (entry.Equals(new HashEntry())) | |
{ | |
continue; | |
} | |
var value = entry.Value.ToString(); | |
if (string.IsNullOrEmpty(value)) | |
{ | |
continue; | |
} | |
if (effectiveType == typeof(DateTime)) | |
{ | |
if (value.EndsWith("|UTC")) | |
{ | |
value = value.TrimEnd("|UTC".ToCharArray()); | |
DateTime date; | |
long ticks; | |
if (long.TryParse(value, out ticks)) | |
{ | |
date = new DateTime(ticks); | |
acessor[instance, member.Name] = DateTime.SpecifyKind(date, DateTimeKind.Utc); | |
} | |
} | |
else | |
{ | |
value = value.TrimEnd("|LOC".ToCharArray()); | |
DateTime date; | |
long ticks; | |
if(long.TryParse(value, out ticks)) | |
{ | |
date = new DateTime(ticks); | |
acessor[instance, member.Name] = DateTime.SpecifyKind(date, DateTimeKind.Local); | |
} | |
} | |
} | |
else | |
{ | |
acessor[instance, member.Name] = Convert.ChangeType(entry.Value.ToString(), member.Type); | |
} | |
} | |
return instance; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment