我正在努力将良好的数据库设计概念与良好的面向对象设计联系起来。
传统上,如果我想在转发器中显示新闻报道列表,我会使用以下内容:
<script runat="server">
void ShowNews()
{
rptNewsStories.DataSource = News.GetAllNews(); // Returns a DataTable
rptNewsStories.DataBind();
}
</script>
<asp:Repeater id="rptNewsStories" runat="server">
<ItemTemplate>
<div>
<span class="Title"><%# Eval("Title")"%> (<%# Eval("Location")"%>)</span>
<p>
<%# Eval("Summary")"%>
</p>
<ul>
<li>Added by: <%# Eval("AddedByFullName")%></li>
<li>Added on: <%# Eval("AddedOn")%></li>
</ul>
</div>
</ItemTemplate>
</asp:Repeater>
此处 News.GetAllNews()会返回 DataTable ,这只是存储过程返回的转储。写入存储过程是为了使用连接返回数据,因此它不止一个表的数据。
这样做的好处在于,在数据库中,存储过程可以查找谁从新闻表中存在的 AddedByID 添加新闻报道并返回人员全名,返回 AddedByFullName 值。
但是,如果我尝试放弃使用DataTable而是返回News对象的List,我会得到以下结果:
<script runat="server">
void ShowNews()
{
rptNewsStories.DataSource = News.GetAllNews(); // Returns a List<News>
rptNewsStories.DataBind();
}
</script>
<asp:Repeater id="rptNewsStories" runat="server">
<ItemTemplate>
<div>
<span class="Title"><%# Eval("Title")"%> (<%# Eval("Location")"%>)</span>
<p>
<%# Eval("Summary")"%>
</p>
<ul>
<li>Added by: <!-- Here there is only a AddedByUserID, not an AddedByFullName value --></li>
<li>Added on: <%# Eval("AddedOn")%></li>
</ul>
</div>
</ItemTemplate>
</asp:Repeater>
但是现在我的问题是,我想要显示的某些值(如 AddedByFullName )在News对象中不存在,因为它们不是明确设置的,而不是从对象中的查找ID中检索。
我想返回对象而不是DataTables,但我不知道弥合这个差距的最佳方法。
我是否:
*在新闻类中为可以从数据库返回的与此数据相关的每个附加值创建其他属性?
*对于具有大量附加值的特定情况,请坚持使用 DataTables 吗?
或者我完全走错了轨道!
答案 0 :(得分:4)
您的选择受到您愿意用作数据访问的基础技术的限制。目前,VS工具集和.Net框架支持多种替代方案:
DataTable
个对象。IQueryable<T>
和LINQ语法。除此之外,所有ADO.Net类型的数据集都允许您指定导航关系,无论是急切地还是延迟加载。在你喜欢描述这些技术的自然习惯的情况下,将在设计者中明确地模拟新闻文章和作者之间的关系,让框架处理加载适当数据和适当类型的问题,最终意义连接问题由应用程序数据访问层(框架)隐式处理,而不是由显式创建的存储过程处理。
技术的选择将在您的代码中无处不在,从您获取数据的方式到显示方式以及更新方式,这些技术都不容易互换。就个人而言,我发现权力和复杂性的正确平衡是LINQ to SQL。
答案 1 :(得分:0)
好问题:
您可以采取以下几种方法:
您可以检索转发器绑定事件所需的其他数据,并将其填充到返回的每条新闻记录的“占位符”中。由于额外的查询,这会产生性能问题,但它会起作用。
如果可能的话,我会修改新闻对象以包含其他信息,或者创建一个从新闻对象继承的对象,该对象中包含其他信息或属性。
希望这会有所帮助:-) +1
编辑/注释: 我认为你在设计中看到的摩擦是你没有承认你的新闻对象和我称之为作者/贡献者之间的“有 - ”关系。您在查询中进行的连接只是掩盖了对象模型中关系的缺失。
答案 2 :(得分:0)
你可以试试这个,也许不是更好的解决方案:
void ShowNews()
{
User[] usersConcerned = News.GetAllUsersLinkedWithNews(); //only return the users concerned by the news
List<News> news = News.GetAllNews();
foreach(News item in news)
{
item.AddedByUser = usersConcerned.FirstOrDefault(u=>u.Id == item.AddedByUserID);
}
rptNewsStories.DataSource = news ;
rptNewsStories.DataBind();
}