Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 需要应用程序设计方面的帮助吗_C#_Asp.net_Design Patterns_Architecture_Mvp - Fatal编程技术网

C# 需要应用程序设计方面的帮助吗

C# 需要应用程序设计方面的帮助吗,c#,asp.net,design-patterns,architecture,mvp,C#,Asp.net,Design Patterns,Architecture,Mvp,因此,我希望得到一些关于以下情况下设计类和存储数据的最佳方法的反馈: 我有一个名为Tasks的界面,如下所示: interface ITask { int ID{ get; set;} string Title {get; set;} string Description{get; set;} } 我希望能够根据使用应用程序的用户创建不同类型的任务…例如: public class SoftwareTask: ITask { //ITask Implementa

因此,我希望得到一些关于以下情况下设计类和存储数据的最佳方法的反馈:

我有一个名为Tasks的界面,如下所示:

interface ITask
{
    int ID{ get; set;}
    string Title {get; set;}
    string Description{get; set;}
}
我希望能够根据使用应用程序的用户创建不同类型的任务…例如:

public class SoftwareTask: ITask
{
    //ITask Implementation
    string BuildVersion {get; set;}
    bool IsBug {get; set;}

}

public class SalesTask: ITask
{
    //ITask Implementation
    int AccountID {get; set;}
    int SalesPersonID {get; set;}
}
因此,在我看来,我可以在数据库中创建一个Tasks表,其中包含与ITask接口匹配的列,以及将更多特定任务的所有属性推送到一列中的列(或者甚至可以将task对象序列化到一列中)

为每种任务类型创建一个表,以存储该类型特有的属性

我现在真的不喜欢这两种解决方案。我需要能够创建不同类型的任务(或任何其他类),这些任务通过基本接口共享一组共同的核心属性和方法,但能够以一种易于搜索和筛选的方式存储它们的唯一属性,而无需为每种类型创建一组数据库表

我已经开始研究插件体系结构和策略模式,但我不认为这两种模式都能解决我在存储和访问数据方面的问题


非常感谢您的帮助或推动

您可能应该从ORMs如何处理这个问题入手,比如

考虑到ITask是一个接口,您可能应该选择TPC(每种具体类型的表)。当您将其作为基类时,TPT和TPH也是可选的。您的第二种方法(每种类型一个表)是解决此问题的标准方法,而实现它需要付出更多的努力才能更好地适应大多数数据库的关系模型,并保持数据的一致性和内聚性表示。每个具体类型使用一个表的方法效果很好,并且与大多数ORM库(如EntityFramework和NHibernate)兼容

但是,当子类型的数量非常大或子类型是动态创建的时,有时会使用两种替代方法。

备选方案#1:键值扩展表。这是一个表,每个要存储的额外数据字段有一行,一个返回核心表(任务)的外键,以及一个指定字段类型的列。它的结构通常类似于:

TaskExt Table
=================
TaskID     : Number (foreign key back to Task)
FieldType  : Number or String (this would be AccountID, SalesPersonID, etc)
FieldValue : String  (this would be the value of the associated field)
TaskExt Table
=================
TaskID   : Number  (foreign key back to task)
Data01   : String
Data02   : String
Data03   : String
Data04   : String
Data05   : Number
Data06   : Number
Data07   : Number
Data08   : Number
Data09   : Date
Data10   : Date
Data11   : Date
Data12   : Date
// etc...
备选方案#2:类型映射的扩展表。在此备选方案中,您创建一个表,其中包含一组不同数据类型(数字、字符串、日期/时间等)的可空列,名称为DATA01、DATA02、DATA03。。。等等对于每种类型的任务,选择列的子集并将它们映射到特定字段。因此,DATA01可能最终成为SoftwareTask的BuildVersion和SalesTask的AccountName。在这种方法中,您必须在某个位置管理一些元数据,以控制将特定字段映射到哪个列。类型映射表通常类似于:

TaskExt Table
=================
TaskID     : Number (foreign key back to Task)
FieldType  : Number or String (this would be AccountID, SalesPersonID, etc)
FieldValue : String  (this would be the value of the associated field)
TaskExt Table
=================
TaskID   : Number  (foreign key back to task)
Data01   : String
Data02   : String
Data03   : String
Data04   : String
Data05   : Number
Data06   : Number
Data07   : Number
Data08   : Number
Data09   : Date
Data10   : Date
Data11   : Date
Data12   : Date
// etc...

选项#1的主要好处是,您可以根据需要动态添加任意多个不同的字段,甚至可以支持一定程度的向后兼容性。然而,一个显著的缺点是,即使是简单的查询也会变得很有挑战性,因为对象的字段被旋转到表中的行中。取消激励是一项既复杂又常常表现不佳的操作

选项#2的好处是易于实现,并且保留了行之间的1对1对应关系,使得查询变得简单。不幸的是,这也有一些缺点。第一个是列名完全没有信息,您必须参考一些元数据字典来了解哪些列映射到哪种任务类型的字段。第二个缺点是,大多数数据库将表上的列数限制在相对较小的数目(通常为50-300列)。因此,您只能使用这么多的数值、字符串、日期时间等列。因此,如果键入的日期时间字段多于表支持的日期时间字段,则必须使用字符串字段存储日期,或创建多个扩展表


请预先警告,大多数ORM库都不提供对这两种建模模式的内置支持。

您应该创建一个二进制字段,2=bug,4=enhancement 8=另一种。这样可能会变得更灵活。只是一个建议。那叫旗子。在这里,上面概述的属性是不相关的,只是为了说明子类型将有一些独特的属性添加到ITask中。我不会在SoftwareTask类上创建IsBug属性…我只是想举个例子…但是谢谢你找Flavio!!嗯……是的,我在项目中使用了NHibernate,目前我的大多数类型都映射到一个表。我只是认为为每个“子类型”创建一个表可能会导致性能问题。例如,我将有一个任务列表,它将显示所有打开的任务(无论子类型如何)。如果我有10种不同类型的任务,那么在我看来,查询11个表来构建结果集将是一个昂贵的查询。我不喜欢备选方案#2,因为它太快变得令人困惑,而且是维护的噩梦。我还试图记住搜索和过滤功能。@Cognotronic:TPT模型有时会出现性能问题,但可以通过在超类型表上添加鉴别器字段和应用适当的索引来解决这些问题。我一开始不会担心性能——从正确建模数据开始。然后进行测试和优化,直到达到可接受的性能水平。