更新
根据@aman的观察,这是有关我的应用程序业务逻辑的更多信息,“ ”可以使您从业务代码所依赖的字典中提取那些元素,并用它们的完好表达。定义的属性” 。
应用程序的相关部分是(金融)产品的注册表。该应用程序允许高级用户定义产品上的其他字段,还可以定义有限的业务逻辑。例如。他们可以定义一个RiskValue
类型的decimal
和一个RiskColor
类型的string
的字段以及一段可以说
如果RiskColor大于1.5,则RiskColor应该为“红色”
现在,此业务逻辑需要能够将RiskColor
强制转换为decimal
才能进行比较,这就是问题所在。
基于以上定义,可以在运行时生成一个类,如下所示:
public class Product
{
public decimal RiskValue { get; set; }
public string RiskColor { get; set; }
public void BusinessLogic( )
{
if( RiskValue > 1.5M)
RiskColor = "Red";
}
但是我不确定我要走那条路线。
我有一些模型类(在C#中),其中某些属性在编译时未知。所以我有一个
[BsonExtraElements]
IDictionary<string,object> ExtraElements {get;}
(实际上BsonExtraElements遵循惯例,但我认为这并不重要)。
其中一些属性的类型为System.Decimal
,例如
obj.ExtraElements["PropertyX"] = 1.000M;
将对象保存到MongoDB时,它会像这样被序列化:
{
...
"PropertyX" : NumberDecimal("1.000"),
}
这是我的期望。
但是,当我将对象读回模型时,该属性的值为MongoDB.Bson.Decimal128
类型,而不是预期的System.Decimal
类型。
大多数应用程序(数据层除外)都不了解底层的存储机制,这也是为什么我通过约定而不是通过属性(包含我的模型的程序集)注册[BsonExtraElements]
的原因没有对MongoDB驱动程序的引用)。我正在寻找不需要用MongoDB特定代码乱扔我的代码的解决方案。我希望有一个我错过的标志,或者希望以某种方式制定自定义约定以将其修复在驱动程序级别。
目前,我已经通过在名为IDictionary<string,object>
的类中实现ExtraElementsDictionary
并在每个操作上通过此方法传递值来解决了这个问题:
private static object FixValue( object value )
{
if( value == null ) return null;
if( value.GetType( ).FullName == "MongoDB.Bson.Decimal128" )
{
return decimal.TryParse( value.ToString( ), out var dec ) ? dec : default;
}
return value;
}
我还考虑过在数据层进行此操作,例如
public MyModel GetMyModelById(string id)
{
// actual retrieval of object
FixDecimal128(obj.ExtraElements);
return obj;
}
但是必须有更好的方法吗?
答案 0 :(得分:0)
更新:
由于您不希望业务逻辑了解数据库库使用的基础类型,因此我想您也已经为那些存在此类规定的值具体定义了用途,否则将不会很有道理。
在这种情况下,您应该有可能从业务代码所依赖的字典中提取那些元素,并用其明确定义的属性来表示它们。我认为这将是最干净的方法:
public decimal ValueThatMyBusinessCodeUses { get; set; }
BsonSerializer.RegisterSerializer<IDictionary<string, object>>(new CustomDictionarySerializer());
关于如何实现字典序列化程序,请查看Serialization上的MongoDB文档。
MongoDB库中有各种帮助程序方法,它们允许在MongoDB使用的C#类型和BSON类类型之间进行转换。
如果您有一个基于MongoDB.Bson.Decimal128
的值,则可以将其简单地转换为十进制,如下所示:
Decimal128 value = 2.4M;
decimal result = (decimal)value;
如果您有一个基于MongoDB.Bson.BsonDecimal128
的值,则可以执行以下操作:
BsonDecimal128 value = new BsonDecimal128(2.4M);
decimal result = value.AsDecimal;