我有两张桌子:
dbo.Dashboards
Id (int PK) Title(nvarchar) WidgetIds(nvarchar)
1 Test [1,2]
dbo.Widgets
Id (int PK) Details(nvarchar)
1 {'text': 'some data'}
2 {'text': 'test'}
预期产出:
Dashboard.Id Dashboard.Title Widget.Id Widget.Details
1 Test 1 {'text': 'some data'}
1 Test 2 {'text': 'test'}
我想通过使用Entity Framework获取带有指定小部件的仪表板。
我的第一个解决方案是获取dbo.Dashboards
然后dbo.Widgets
。之后我可以在后端合并它,但这不是最好的做法。
是否有任何选项可以获取带有指定Widget列表的Dashboards?
函数Include()
不起作用,因为表之间没有FK关系。
答案 0 :(得分:1)
在我看来,Dashboards
和Widgets
之间存在多对多的关系:每个Dashboard
都有零个或多个Widgets
,每个{{1}由零或更多Widget
使用。
在适当的数据库中,您将拥有单独的junction table。显然您选择不使用此模式,但创建一个字符串,其中包含“仪表板”具有的小部件的文本表示。
如果您打算创建一个认真的应用程序,我强烈建议您 在多对多关系中使用标准模式
如果不这样做,您的所有疑问都会更加困难。想象一下,如果要删除Widget,您将遇到的问题。您必须检查每个仪表板的文本表示,以检查您要删除的窗口小部件是否在某处使用并更改它。
如果您想根据Entity Framework Code-First Conventions配置多对多关系,您将拥有以下内容:
Dashboards
因为您遵守惯例,所以这是实体框架需要了解的所有内容,以了解您要在Dashboards和Widgets之间配置多对多关系。实体框架将为您创建联结表。每当您向控制板添加Widget时,它都会自动更新此表。每当您想要使用其窗口小部件获取仪表板时,它也会创建正确的连接,或者使用使用它们的Dasheboards获取窗口小部件。
您的查询非常简单:
class Dashboard
{
public int Id {get; set;}
public string Title {get; set;}
// every Dashboard has zero or more Widgets
public virtual ICollection<Widget> Widgets {get; set;}
... // other properties
}
class Widget
{
public int Id {get; set;}
// every Widget is used in zero or more Dashboards
public virtual ICollection<Dashboard> Dashboards{get; set;}
... // other widget properties
}
class MyDbContext : DbContext
{
public DbSet<Dashboard> Dashboards {get; set;}
public DbSet<Widget> Widgets {get; set;}
}
如果你坚持惯例,看看它有多容易吗?
如果您真的想要使用外键的模糊方法,则需要一个函数来删除widgetIds中的方括号和逗号,将字符串拆分为子字符串,将它们解析为数字,然后进行连接。 / p>
但在您计划继续这条道路之前,请尝试如何添加Widget和Dashboard。如何将Widget添加到仪表板,如何删除Widget。我认为将数据库改造成适当格式所需的时间远远少于实现这些功能所需的时间
答案 1 :(得分:0)
解决方案1:
您需要重新构建dbo.dashboards表。将dbo.dashboards的列布局更改为 Auto_Generated_ID,Unique_Identifier(PK),标题,WidgetIds
我知道上面的专栏重组是以糟糕的方式完成的。但是这仍然适用于你的情况。
重新设计之后,您可以使用dbo.dashboards和dbo.widgets之间的连接以高效的方式检索它。
解决方案2:
以下规范化的表将适用于您的情况
<强> dbo.dashboard 强>
id,title(columns)
<强> dbo.dashboard_widget 强>
id,dashboard_id,widget_id(列)
<强> dbo.widgets 强>
id,details(columns)
<强>查询:强>
选择d.id,d.title,dw.widget_ids,w。详细信息来自dbo.dashboard d INNER JOIN dbo.dashboard_widget dw ON d.id = dw.dashboard_id INNER JOIN dbo.widgets w ON dw.widget_id = w.id其中d.id =&lt;&lt;身份证号码&gt;&gt;