MHO*_*OOS 10 c# state design-patterns software-design state-machine
我是状态设计模式的新手,我找不到将对象的不同状态保存到数据库的正确示例(在我的例子中是SQL Server).该场景与下一篇文章中描述的示例非常相似[几乎相同],但是我没有找到将状态持久保存到数据库的适用解决方案.你们可以推荐一个链接或者可能举个例子吗?
另外:如何在运行时枚举所有不同的ConcreteState类型?举例来说,如果你有10个不同的国家,你声明与10个不同成员的EnumStates,并给每一个成员的ConcreteState关联EnumStates成员,或者你通过得到的ConcreteState的子类得到所有的不同的状态?
为了您的信息,我需要能够根据不同的状态搜索实体.
国家实体本身没有国家,所以你需要保存的只是每个国家的身份.将State类名保存在数据库中并不是一个好主意,因为如果更改了State类名,则必须更改数据库.代替,
要在加载对象时返回状态,也可以
无论哪种方式,您都需要能够从Enum值转到State.通过遍历所有相关的State类来执行此操作,直到找到其标识值匹配的类.
那么,相关国家是什么?这取决于谁在写国家课程.
在简单的情况下,您控制整个程序并且程序中的所有State类都是State-having对象的潜在成员,您可以循环遍历State超类或接口的所有子类或实现者,如下所示:获取实现接口的所有类型.
如果由于某种原因存在您不想循环的状态类,只需在一个常量中定义一个您想要循环的列表,或者在配置中定义(如果您想更改它而不更改代码) .
如果使您的状态类列表很慢,只需在程序启动或首次使用时执行一次.如果您对列表进行硬编码,请不要在具有State的类中(它应该独立于特定的状态)或State超类(这会引入循环依赖); 将列表放在你的程序中更高(依赖性)或(如Farhad所建议的)在它自己的类中.
有很多例子说明如何使用State来保持对象 ; 这一个相对简单.
不要尝试将状态转换为表中的列,这是行不通的。
而是使用 JSON.NET 序列化状态,因为它支持继承。然后将它存储在一个表中,如:
create table OrderStates
(
OrderId int not null,
Data nvarchar(MAX) not null
);
Run Code Online (Sandbox Code Playgroud)
如果需要,可以包含更多列,但仅包含用于标识状态用途所需的列。
要在 JSON.NET 中激活继承支持,您必须使用:
var json = JsonConvert.SerializeObject(yourState, typeof(StateBaseClass), JsonConvert.DefaultSettings)`.
using (var cmd = sqlConnection.CreateCommand())
{
cmd.CommandText = "INSERT INTO OrderStates (OrderId, Data) VALUES(@OrderId, @Data)";
cmd.Parameters.AddWithValue("OrderId", orderId);
cmd.Parameters.AddWithValue("Data", json);
cmd.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)
反序列化时也是如此,使用时指定基类JsonConvert.DeserializeObject()
。
如何在运行时枚举所有不同的 ConcreteState 类型?例如,如果您有 10 个不同的状态,您是声明一个具有 10 个不同成员的 EnumStates 并为每个 ConcreteState 成员指定一个关联的 EnumStates 成员,还是通过获取 ConcreteState 的子类来获取所有不同的状态?
子类。这是能够引入新状态或删除旧状态而无需修改其他类的唯一方法。对现有类的每次修改都会引入错误。