ServiceStack.Redis с F# не хранит данные. Но почти такой же код в C# работает
Я играю сегодня вечером с F# и Redis. Я использую ServiceStack.redis для подключения к редису MSOpenTech, работающему на локальном хосте. В целях тестирования я пытался сохранить цену биткойна в redis с помощью кода, подобного следующему:
let redis = new RedisClient("localhost")
redis.FlushAll()
let redisBitstamp = redis.As<BitstampLast>()
let last = {Id = redisBitstamp.GetNextSequence(); Timestamp = 1386459953; Value=714.33M}
redisBitstamp.Store(last)
let allValues = redisBitstamp.GetAll()
allValues.PrintDump()
К сожалению, результат от PrintDump был:
[
{
__type: "Program+BitstampLast, RedisSave",
Id: 0,
Timestamp: 0,
Value: 0
}
]
Просто для целей тестирования я запустил практически идентичный код в C# на том же экземпляре Redis:
class BitstampLast
{
public Int64 Id { get; set; }
public int Timestamp { get; set; }
public decimal Value { get; set; }
}
class Program
{
static void Main(string[] args)
{
var redis = new RedisClient("localhost");
redis.FlushAll();
var redisBitstamp = redis.As<BitstampLast>();
var last = new BitstampLast() {Id = redisBitstamp.GetNextSequence(), Timestamp = 1386459953, Value=714.33M};
redisBitstamp.Store(last);
var allValues = redisBitstamp.GetAll();
allValues.PrintDump();
}
}
И результат...
[
{
__type: "CSharpRedis.BitstampLast, CSharpRedis",
Id: 1,
Timestamp: 1386459953,
Value: 714.33
}
]
Итак, что мне не хватает? Почему это работает в C#, а не в F#?
РЕДАКТИРОВАТЬ: BitstampLast определяется следующим образом:
type BitstampLast = {Id:int64; Timestamp:int; Value:decimal}
что неправильно, потому что это должно быть:
type BitstampLast = {mutable Id:int64; mutable Timestamp:int; mutable Value:decimal}
И теперь это работает. Тогда следующие вопросы - почему это должно быть изменчивым? Redis каким-то образом связывается с этим объектом?
1 ответ
Многие из библиотек ServiceStack (например, Serialization, Auto-mapping и т. Д.) Работают с POCO, которые имеют конструктор по умолчанию и свойства для записи, которых у неизменяемых записей F# по умолчанию нет.
Лучший способ создать POCO в F# - это украсить его CLIMutable
Атрибут F# 3.0 Language Feature, который создает тип POCO с общедоступными методами получения и установки для всех свойств, которые доступны в коде C#, но все еще ведут себя как неизменяемые типы в F#, например:
[<CLIMutable>]
type BitstampLast = { Id:int64; Timestamp:int; Value:decimal }