C# 在数据库中保存类类型的最佳方法?
在数据库中用什么方法来表示“type” 我有一个基类C# 在数据库中保存类类型的最佳方法?,c#,database-design,types,C#,Database Design,Types,在数据库中用什么方法来表示“type” 我有一个基类Action,它由许多子类继承Action有Id、Name等成员,所有这些成员都对应于数据库中名为Action的表中的等效列。所以action表如下所示: id | name | type public abstract class Action { public enum Kind { ControlAction = 1, UpdateAction = 2, etc
Action
,它由许多子类继承Action
有Id
、Name
等成员,所有这些成员都对应于数据库中名为Action
的表中的等效列。所以action
表如下所示:
id | name | type
public abstract class Action
{
public enum Kind
{
ControlAction = 1,
UpdateAction = 2,
etc
}
public abstract Kind ActionType { get; }
}
public class ControlAction : Action { public override Kind ActionType { get { return Kind.ControlAction; } } }
public class UpdateAction : Action { public override Kind ActionType { get { return Kind.UpdateAction; } } }
类型
列表示它是什么操作。在我的代码中,它们对应于从父Action
派生的子类。现在,如何将类的类型保存到数据库中的类型字段中
db中的类型列可以是任何数据类型
选项:
action.GetType().ToString()另存为数据库中的字符串。并通过使用反射将类型的字符串表示形式转换为其原始类型,从db返回操作类型但如果将来更改类名,这将有问题。
TypeAttribute
装饰它,类似于:
public abstract class Action
{
public enum Kind
{
[Type(typeof(ControlAction))]
ControlAction = 1,
[Type(typeof(UpdateAction))]
UpdateAction = 2,
etc
}
public abstract Kind ActionType { get; }
}
public class ControlAction : Action { public override Kind ActionType { get { return Kind.ControlAction; } } }
public class UpdateAction : Action { public override Kind ActionType { get { return Kind.UpdateAction; } } }
//etc
这看起来不错,只是从这里开始,我必须为每个类创建一个枚举。而且感觉有点太多的工作要做
静态哈希表,将类绑定到int
值可能有点不可读。有更好的解决方案吗?我会从第三个解决方案开始,使用一个哈希表,因为它看起来确实是更干净的设计。我会将其管理委托给数据库 毕竟,这不是关系数据库最擅长的,在两个实体之间创建关系(在您的例子中是操作和类型)吗?另一个优点是最终得到了规范化的模式(当然,到目前为止,类型表只有一列,即其名称,但是规范化允许您在将来需要时轻松地向类型添加其他属性,这就是为什么它作为一种设计更简洁的原因) 模式应该是这样的:
id | name | type
public abstract class Action
{
public enum Kind
{
ControlAction = 1,
UpdateAction = 2,
etc
}
public abstract Kind ActionType { get; }
}
public class ControlAction : Action { public override Kind ActionType { get { return Kind.ControlAction; } } }
public class UpdateAction : Action { public override Kind ActionType { get { return Kind.UpdateAction; } } }
行动表
action_id(PK) | name | type_id (int, FK to Type table)
type_id(PK) | type_name
类型表
action_id(PK) | name | type_id (int, FK to Type table)
type_id(PK) | type_name
现在,如果一个类的名称在将来发生更改,那么您就安全了(您的第一个字符串类型命题引起的担忧)。实际上,您所要做的就是更改相应的type
表行中的type\u name
值,并且所有Action
行仍将通过type\u id
链接到此行,该id在创建后不会更改(这里没有问题,因为它没有任何“业务意义”)
并且您拥有3中的哈希表(类型表),格式可读,因为RDMBS负责管理哈希表的键(类型idPK)
请注意,您不必将类绑定到与
type\u id
列对应的int
值,而是通过查找类类型(type\u name
)从type
表中获取type\u id
。我将使用您的第一个选项并使用反射。您似乎更希望添加新的操作类型,而不是更改现有的类名,因此使用反射序列化类型的方便性更有用。
然后,您就可以拥有一个实用程序类,用于序列化操作并从其类型字符串中恢复操作。我最终使用了选项2,但属性的混乱程度较低。大概是这样的:
id | name | type
public abstract class Action
{
public enum Kind
{
ControlAction = 1,
UpdateAction = 2,
etc
}
public abstract Kind ActionType { get; }
}
public class ControlAction : Action { public override Kind ActionType { get { return Kind.ControlAction; } } }
public class UpdateAction : Action { public override Kind ActionType { get { return Kind.UpdateAction; } } }
最大的优点是(即使它意味着更多的键入),它强制执行一个与类类型关联的数值
现在,类到int只是:
非常快
但要将int转换为类实例(或类类型),我必须创建每个子操作类型的实例,并比较其ActionType
属性以匹配输入的int值。这将是缓慢的。但我可以缓存一些东西,让它更快。比如:
public abstract class Action
{
public enum Kind
{
[Type(typeof(ControlAction))]
ControlAction = 1,
[Type(typeof(UpdateAction))]
UpdateAction = 2,
etc
}
public abstract Kind ActionType { get; }
}
public class ControlAction : Action { public override Kind ActionType { get { return Kind.ControlAction; } } }
public class UpdateAction : Action { public override Kind ActionType { get { return Kind.UpdateAction; } } }
//etc
static只读字典)。我甚至可以通过
好处:
创建新类(无属性)时的麻烦更少
强制将int绑定到类类型
速度适中,缓存充足
您正在尝试创建ORM吗?或者,您真的需要(对于边缘情况可能)将类类型信息保存在数据库中,以便其他应用程序可以重用吗?@edsioufi不,这与orm无关。每个子操作(如ControlAction
,UpdateAction
等)都是由客户端创建的操作。每种操作类型都有自己的信息集,客户机需要这些信息。现在我需要一种方法将客户端创建的操作保存到数据库中。稍后,当我从db加载这些不同的操作时,我需要将ControlAction
从UpdateAction
中分离出来。此外,使用字符串作为ActionType,检查类型表(如果ActionType已经存在)并改为使用id(如果不存在,则将其添加到类型表),您可以创建类似缓存的东西(用于缓存具有id的actiontype名称的字典)@edsioufi,我不确定它在类名更改时有什么帮助。类型表中的type\u name
应该是什么?Jeroen提出了一个很好的观点,这就是你的意思吗?不,在编辑之后似乎是这样。我如何在type表中进行类型查找?如果type\u name
只是类的type
的字符串表示,那么这就是不起作用。@edsioufi我现在明白了。你说的是,如果类的名称更改,我必须在type\u coulmn
中更改字符串名称。还不错。但我可能会实现更简单的东西:)@nawfal Cool:)。TBH这实际上是一个简单的关系数据库用例,您只需要一个连接来获取所有数据,一个查找来插入。当然是你的电话:)。班名可能会改变