我已经在层次结构,树,组合键和SQL中的更多问题上阅读了很多帖子,但我无法找到所需的信息。我正在使用EF6和SQL,C#。
案例:
让我说我有以下型号。所以应用程序可以在每个平台上(或者只在其中的一个或两个平台上。应用程序将是一个基类,如果从代码说起,OSX和Windows和PlatformX会使他不知所措。)。但是,应用程序可以针对每个平台进行审核,并且审核可以适用于多个平台。因此,我试图建立一个不需要将评论分成3个不同表格的数据库。
有人在sql数据库中如何对此进行建模有一个很好的例子吗?或者这不可能吗?
一些必需的查询将是: - 获取应用程序的所有指定类型(OSX,winodws等..)? - 获取应用程序类型的所有评论。 - 获取应用程序的所有评论。 - 通过审核获取所有申请。 (然后我可以找出它是哪种类型吗?)
答案 0 :(得分:1)
据我所知,Application
是OSX
,Windows
和PlatformX
的基础实体。
我的第一句话是,如果您的~Value
字段是每个组件的平台特定字段,例如
----------- ------------------
| Windows | | OSX |
----------- -----------------|
| WinApi | | SupportsMobile |
| TempDir | | WrittenLang |
----------- ------------------
然后你可能想为Application
创建一个表,它的主键是一个标识字段。建议其他实体为单独的表,但会使用Application
的主键作为自己的主键,即一对一的关系。
如果您的情况不符合以上条件且您的表格将包含Value1
,Value2
和Value3
以及相同的数据类型,那么我强烈建议您合并所有将类分成一个表并添加整数标志Platform
。因此,您最终只能使用两个表来简化您的工作,并且不会截断功能。
然而,对于这两种情况,使用Review的案例解决方案是相同的。我建议你将Application
表连接到Review
表,这样可以节省你很多时间。
您的所有查询问题:是的,您可以执行所有查询。
修改
好的,让我告诉你我的愿景。
应用程序( ApplicationId ,名称,价格,命名空间)
OSX( ApplicationId * ,OSXValue1,OSXValue2,OSXValue3)
Windows( ApplicationId * ,WindowsValue1,WindowsValue2,WindowsValue3)
PlatformX( ApplicationId * ,XValue1,XValue2,XValue3)
查看( ReviewId ,ApplicationId *,FullName,ReviewText)
NB 请注意,我使用PascalCase作为字段名称。这是使用EF的一个很好的约定,因为字段将映射到属性名称(按照惯例),并且不会破坏.NET应用程序中的整体命名。
ApplicationId
表中的Application
是一个标识字段,是主键。在表OSX
,Windows
和PlatformX
中定义ApplicationId
字段,将其定义为主键,并在ApplicationId
中引用Application
字段的外键每个人的表。
这是你存储它的方式。
从实体框架开始 按如下方式定义您的类
public class Application {
private ICollection<Review> _Reviews;
public Int64 ApplicationId { get; set; }
/*Other fields*/
public Windows Windows { get; set; }
public Osx Osx { get; set; }
public PlatformX PlatformX { get; set; }
public ICollection<Review> Reviews {
get { return _Reviews = _Reviews ?? new List<Review>(); }
set { _Reviews = value; }
}
}
public class Osx {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[ForeignKey("Application")]
public Int64 ApplicationId { get; set; }
/*Other fields*/
public Application Application { get; set; }
}
public class PlatformX {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[ForeignKey("Application")]
public Int64 ApplicationId { get; set; }
/*Other fields*/
public Application Application { get; set; }
}
public class Windows {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[ForeignKey("Application")]
public Int64 ApplicationId { get; set; }
/*Other fields*/
public Application Application { get; set; }
}
public class Review {
public Int64 ReviewId { get; set; }
public Int64 ApplicationId { get; set; }
/*Other fields*/
//Convention will catch up the ApplicationId field automatically
public Application Application { get; set; }
}
在这里,您可以通过数据注释定义一些非显而易见的功能,例如:与常规TableName +&#39; Id&#39;不匹配的键。此外,您还指出ApplicationId
字段不是使用DatabaseGeneratedAttribute
自动生成的。
以下查询获取类型为Osx
和Windows
var context = new DemoContext();
var res = context.Osx.Select(x=>x.Application).Union(context.Windows.Select(x=> x.Application));
这是对应用程序的查询及其类型
var res2 = context.Reviews.Select(x => new {
x.Application,
IsOsx = x.Application.Osx != null,
IsWindows = x.Application.Windows != null,
IsPlatformX = x.Application.PlatformX != null
});
您可以根据对象中的布尔值找出类型。