我需要将键值对存储在数据库中。值可以是以下类型之一:bool
,int
,double
,string
,DateTime
。在Set<T>
下面的班级中,操作有效,但Get<T>
会引发InvalidCastException
。
public class PersistedKeyValueStorage
{
AppDbContext _dbContext;
public PersistedKeyValueStorage() : this(new AppDbContext()) { }
public PersistedKeyValueStorage(AppDbContext dbContext)
{
_dbContext = dbContext;
}
public T Get<T>(string Key) {
var record=_dbContext.Set<StoredKeyValueItem>().FirstOrDefault(p => p.Key == Key);
if (record != null) return (T)(object)(record.Value); // here is error
return default(T);
}
public void Set<T>(string Key, T Value) where T : struct
{
var record = _dbContext.Set<StoredKeyValueItem>().FirstOrDefault(p => p.Key == Key);
if (record != null) record.Value = Value.ToString();
else _dbContext.Set<StoredKeyValueItem>().Add(new StoredKeyValueItem { Key = Key, Value = Value.ToString() });
_dbContext.SaveChanges();
}
}
// class usage
var skvs = new PersistedKeyValueStorage();
skvs.Set("test.int", (int)123);
skvs.Set("test.boolean", true);
skvs.Set("test.datetime", DateTime.Now);
ViewBag.testint= skvs.Get<int>("test.int");
ViewBag.testbool = skvs.Get<Boolean>("test.boolean");
ViewBag.testdate= skvs.Get<DateTime>("test.datetime");
答案 0 :(得分:1)
您将所有值存储为商店中的字符串。
所以当你把它们拿回来时,它们就会成为弦乐。
要从object
转到T
,那么实际的对象必须是:
T
T
int
是值类型,但在执行(int)obj
时,您只能取消内部的值,而且必须是int
。在您的情况下,它是string
。这不会奏效。
相反,在这种情况下,您必须使用转换层与您的存储类型string
进行转换。
对于某些类型,您可以尝试将代码更改为:
return (T)Convert.ChangeType(record.Value, typeof(T));
但是,这不会处理所有符合T
条件的类型。