interface ICommand { void Execute(); }
然后有几个命令从这个接口继承.
class CommandA : ICommand { int x; int y; public CommandA(int x,int y) { ... } public void Execute () { ... } } class CommandB : ICommand { string name; public CommandB(string name) { ... } public void Execute () { ... } }
现在我想将这些命令存储在一个数据库中,使用通用的方法,然后将它们从DB中加载到List< ICommand>中.并执行它们的Execute-method.
现在我刚刚在DB中有一个表命名,这里我存储一个对象的字符串序列化.基本上表中的列是:id | commandType | commaseparatedListOfParameters.虽然这是非常简单的,并且适用于加载所有命令,我不能轻松地查询命令,而不使用子字符串和其他模糊的方法.我想要一个简单的方法来选择id id,x,y FROM commandA_commands WHERE x = …并且同时有一个通用的方法从命令表中加载所有的命令(我想这将是某种命令A_命令的UNION / JOIN,commandB_commands等).
重要的是要添加一个新的命令,在数据库中没有太多的人工操作,或手动创建序列化/解析方法.我已经有了大量的新的和新的被添加和删除所有的时间.我不介意创建一个命令表查询生成工具,但如果这是最佳解决方案所必需的.
最好的我可以想到自己是一个常见的表,如id | commandType | param1 | param2 | param3 | etc ..这不是比我目前的解决方案好多了(实际上更糟糕),因为许多命令将需要空参数和数据类型会有所不同,所以我不得不再次使用常见的字符串转换,并为每个字段的大小调整最大的命令.
编辑:在这里找到类似的问题Designing SQL database to represent OO class hierarchy
解决方法
>一个基类/接口的表,用于存储所有类型的公共数据
>每个降序类中的一个表,它使用与基表完全相同的主键(这是sql Server 2011序列btw的好用例)
>一个保存要存储的类型的表
>将所有这些表连接在一起的视图,以便轻松加载/查询对象
在你的情况下,我会创建:
>表CommandBase
> ID(int或guid) – 命令的ID
> TypeID(int) – 命令类型的ID
>表CommandA
> ID(int或guid) – 与CommandBase表相同的ID
> X(int)
> Y(int)
>表CommandB
> ID(int或guid) – 与CommandBase表相同的ID
>名称(nvarchar)
>表CommandTypes
> ID(int) – 命令类型的ID
>名称(nvarchar) – 命令类型的名称(“CommandA”,“CommandB”,…)
> TableName(nvarchar) – 存储类型的表的名称 – 如果需要某些动态sql,则为usefull – 否则为可选
>查看命令,一些以下的东西:
select cb.ID,a.X,a.Y,b.Name from CommandBase cb left outer join CommandA a on a.ID = cb.ID left outer join CommandB b on b.ID = cb.ID
这种方法的优点是它反映了你的类结构.这很容易理解和使用.
缺点是,当您添加新课程时,它变得越来越麻烦,很难模拟更多的层次结构,如果有很多后代,视图可能会长一英里.
就个人而言,如果我知道子类的数量相对较小并且相对固定,那么我将使用这种方法,因为它需要为每个新类型创建(并维护)一个新的表.但是,该模型非常简单,因此可以创建一个可以为您创建和维护的工具/脚本.