我需要设计使用asp.net web窗体(C#)和MS SQL Server作为一本杂志的网站,这将有每周的问题,后端数据库基于CMS网站。
样本数据
MagazinePages Table
PageID PageName LangID PagePositionNo PageURL PageInheritance //PageID
1 Home 1 10 Default.aspx 0
2 About Us 1 20 Page.aspx 0
3 PageOne 1 10 Page.aspx 2
4 PageTwo 1 20 Page.aspx 2
5 Media 1 30 Page.aspx 0
6 Video 1 10 Videos.aspx 5
8 News 1 40 News.aspx 0
9 Archive 1 50 # 0
10 Publication 1 60 Page.aspx 0
11 SpanishHome 2 10 Default.aspx 0
12 SpanisAboutUs 2 20 Page.aspx 0
------------------------------------------------------------------------------
Magazine
MagazineID MagazineIssueCode LangID MagazineTitle MagazineLiveIssue(CurrentIssue)
1 1 1 Mag Title 0
2 2 1 Mag Title 1
3 1 2 SpanisgMag Title 0
4 2 2 Mag Title 1
------------------------------------------------------------------------------
News Table
NewsID NewsTitle NewsCatID MagazineID Language
1 News one 100 1 1
2 News two 100 1 1
3 news three 200 1 1
4 News four 300 1 1
5 News Five 100 2 1
6 News Six 300 2 1
7 News seven 200 2 2
------------------------------------------------------------------------------
与上述方法的问题是,我可以创建子菜单只有当所有的记录都在上面的例子基于MagazinePages我可以创建子菜单的“关于我们”与多媒体我怎么设计我的数据库,这样我可以拉从不同的表中的数据如按类别消息 (政治,文化...)&问题来自杂志表(问题101,第102,第103 ....)
我打算用这个可能不是很灵活,ASP菜单控制,因为我将有超过100个问题,我的杂志怎么能或者多列菜单与asp.net使用
我的数据库可能有许多流动的,我希望帮助在这方面,这样我就可以使用这个数据库为这个CMS系统。 请随意问任何关于此问题。
补充 :如果我需要从拉所有的菜单名称MagazinePages
表的话很容易,但我一直在问到有没有作为示例所示的菜单结构。 这个问题是我可以生成菜单AboutUs
及Multimedia
从MagazinePages
表,但我没有像政治,经济,...问题101,102,103的任何页面。在此表作为信息存储在不同的表像News Category
的新闻表和问题在Magazine
表。 我宁愿改变我的表的设计和使其灵活读取来自单独的表菜单信息,但我不知道怎么样
新闻表是不是在这个模式显示。
我所做的是我创建ps_Pages表CMS一样的页面,首页,公司简介,联系方式,MediaCentre .....
我存储与杂志页面(这实际上是文章与不同类别或类似的文化,政治,体育,人物标签...)在art_Article
表
为什么没有一个单一的页面处理的内容?
只需拨打Page.aspx?Issue=4&Page=4
然后在你的代码,你知道这是第4期,他们希望第4页,那么你可以在那个翻译,然后决定在布局Page.aspx(或的.vb的.cs)代码。
因此,如
Page.aspx?Issue=4&Style=Article&Content=5
所以在代码,那么你可以去,好吧这是第4期获得数据库项第4期,还好他们想从第4期的内容ID 5,然后把在文章的风格。
这意味着你不必额外页面添加到数据库类型,你可以只是简单地添加内容,你想和它产生的URL访问内容的项目只需要显示的所有内容。
我认为你需要重新评估您的数据库模式。 例如,我想有一个叫做“ParentMenuItems”表
该表将包括所有顶级菜单项(主页,关于我们,问题等),并有儿童菜单中的文字。 然后,你需要有一个具有关系到你的父菜单项的ChildMenu表。
ParentMenuItems:
==============================================================
ID | LinkText | LangID | Other Properties
==============================================================
1 | Home.aspx | 1 | blah blah blah
2 | AboutUs.aspx | 2 | blah blah blah
然后,你可以有另一个表称为“ChildMenuItems”是这样的:
ChildMenuItems:
===============================================================
ID | LinkText | LangID | ParentID | Other Properties...
===============================================================
1 | PageOne.aspx | 1 | 2 | blah blah blah
2 | PageTwo.aspx | 2 | 2 | blah blah blah
该代码可以像这样工作:
SELECT * FROM ParentMenuItems - //SQL to get Items
然后,写一些代码的foreach枚举SQL结果
foreach(var ParentMenuItem in ParentMenuItems)
{
//Get ParentMenuItem ID, run SQL select on child menu items, Example:
//SELECT * from ChildMenuItems where ParentID = ID.FROM.PARENT.RESULT
// Now you have all the child menu items, foreach those and add to repeater control
}
我希望这有帮助。 让我知道如果你有问题。
提示:实体框架将使这个很轻的工作。
我不知道我明白你需要什么,但我会假设你想创建整个系统的菜单,而不是每本杂志的菜单,对不对?
如果是这样,我认为你正在寻找错误的问题:这个问题是不是数据库模式,但你的菜单应该由没有预定义的标准的N个不同的表被自动填写的概念。
我想创建一个菜单表 - 并magazinepages和菜单两种截然不同的表:如果您正在创建一个CMS-like系统,你可能有一个页面,我可以编辑的类别,问题和 - 为什么不 - 菜单项,完全分开从任何其他表。
另外,我想创建一个“标签”系统,在这里我所有的新闻和问题,可以“标记”,而不是放在一个独特的类别。 它将使可能有关于政治和文化的同时谈了消息。 然后,而不是引导用户到许多不同pages.aspx的,你会使用一个content.aspx?标签=政治。 当创建标签,我不得不将此标签添加到菜单表,“新闻”,“问题”,等等。同类别和问题下的选项。
如果它不适合你的需求,你可以尝试这些选项 - 但所有其他解决方案相比,菜单中的特定表项trows“警告,检测未来的问题”,在我的大脑:
1 - 创建一个菜单表,通过以下具体规定填写此表,然后触发像“类别”表中,将截断和调用存储过程的存储过程,改写菜单每次内容变化(听起来像一个快速解决我)
2 -添加“submenu_table”, “submenu_field”, “submenu_condition”等,以magazinepages和使用动态SQL来选择数据(像Set @SQL='Select '+ submenu_field + ' from '+ submenu_table + ' where ' + submenu_condition; Exec(@SQL)
另一个速战速决,重大概慢查询)
(编辑:) 3 - 也有一个在SQL 2008以上hierachyId字段([http://blogs.msdn.com/b/manisblog/archive/2007/08/17/sql-server-2008-hierarchyid.aspx]) 1
创建菜单的表
CREATE TABLE [dbo].[tblMenuMaster](
[MenuID] [int] IDENTITY(1,1) NOT NULL,
[MenuName] [varchar](100) NULL,
[DisplayOrder] [int] NULL,
PRIMARY KEY CLUSTERED
(
[MenuID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
创建子菜单的另一个表
CREATE TABLE [dbo].[tblSubMenuMaster](
[SubMenuID] [int] IDENTITY(1,1) NOT NULL,
[MenuID] [int] NULL,
[SubMenuName] [varchar](100) NULL,
[MainMenuDisplayOrder] [int] NULL,
[DisplayOrder] [int] NULL,
[SubMenuUrl] [varchar](500) NULL,
[VisibleInMenu] [bit] NULL,
PRIMARY KEY CLUSTERED
(
[SubMenuID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
现在去掌握网页.. HTML代码为:
<div class="menubar">
<%--<ul class="tabs">--%>
<asp:Literal ID="ltMenus" runat="server"></asp:Literal>
<%--</ul>--%>
</div>
后面的代码的代码是:
private void GenerateMenus()
{
clsMenu obj = new clsMenu();
System.Data.DataSet ds = new System.Data.DataSet();
String PageName = "";
PageName = Path.GetFileName(Page.AppRelativeVirtualPath);
ds = obj.GetMenusByRole(GetRoleId(), PageName);
StringBuilder sb = new StringBuilder("<ul class='tabs'>");
foreach (System.Data.DataRow row in ds.Tables[0].Rows)
{
sb.Append(String.Format("<li class='{0}'><a rel='{1}' href='{1}' > {2} </a> ", Convert.ToString(row["css"]), ResolveUrl(Convert.ToString(row["PagePath"])), Convert.ToString(row["MenuName"])));
//sb.Append(String.Format("<li '><a rel='{0}' href='{0}' > {1} </a> ", ResolveUrl(Convert.ToString(row["PagePath"])), Convert.ToString(row["MenuName"])));
System.Data.DataTable t = CCMMUtility.GetFilterDataforIntColumn("MenuID", Convert.ToString(row["MenuID"]), ds.Tables[1]);
if (t.Rows.Count > 0)
{
sb.Append("<ul>");
for (int i = 0; i < t.Rows.Count; i++)
{
sb.Append(String.Format("<li><a href='{0}' class='dir' style='cursor: pointer;'>{1}</a></li>", ResolveUrl(Convert.ToString(t.Rows[i]["PagePath"])), Convert.ToString(t.Rows[i]["PageAliasName"])));
}
sb.Append("</ul>");
}
sb.Append("</li>");
}
sb.Append("</ul>");
ltMenus.Text = sb.ToString();
}
它需要存储过程根据菜单的动态调用角色ID像下面
CREATE PROCEDURE [dbo].[proc_GetMenusByRole]
(
@RoleId int,
@PageName varchar(100)
)
AS
SET NOCOUNT ON;
SELECT mm.MenuID, mm.MenuName,dbo.Extract_CssNameForMenuByMenuIDAndPageName(mm.MenuID, @PageName) as css
,dbo.proc_Extract_MenuPageByRoleIDAndMenuID(@RoleId, mm.MenuID)
as PagePath , mm.DisplayOrder FROM tblMenuMaster mm WHERE mm.MenuID IN (SELECT s.MenuID from tblSiteRolePermissions p INNER JOIN
tblSitePages s ON p.fkSitePageId = s.pkSitePageId
WHERE (p.fkRoleId = @RoleId and p.ViewOnly=1))
Union All
select 0 as menuid ,'Change Password' as MenuName,
case @pagename
when 'ChangePassword.aspx' then 'active'
else ''
end as css,'~/User/ChangePassword.aspx' as PagePath, 10000 as Displayorder
ORDER BY DisplayOrder
SELECT s.MenuID, s.pkSitePageId, s.PageAliasName, s.SitePageName,s.pagepath from tblSiteRolePermissions p
INNER JOIN tblSitePages s ON p.fkSitePageId = s.pkSitePageId WHERE (p.fkRoleId =@RoleId and p.ViewOnly=1) ORDER BY s.pkSitePageId
//新的SP从这里开始
CREATE function [dbo].[Extract_CssNameForMenuByMenuIDAndPageName](@MenuID int,
PageName varchar(100))
returns nvarchar(50)
as begin
declare @result nvarchar(50)
set @result = ''
IF EXISTS (SELECT pkSitePageId FROM tblsitepages WHERE (MenuID = @MenuID) AND (UPPER(SitePageName) = @PageName))
BEGIN
SET @result = 'active'
END
return @result
end
//使用的另一种属是
CREATE function [dbo].[proc_Extract_MenuPageByRoleIDAndMenuID]
(@RoleId int, @MenuID int)
returns nvarchar(500)
as begin
declare @result nvarchar(500)
SELECT top 1 @result = s.pagepath FROM tblSitePages AS s INNER JOIN tblSiteRolePermissions AS p ON s.pkSitePageId = p.fkSitePageId
WHERE (p.fkRoleId = @RoleId) AND (s.MenuID = @MenuID) and p.ViewOnly=1
ORDER BY s.pkSitePageId
return @result
end
它只是一种方法可以做到这一点,你可以根据你的要求修改这个.........
proc_Extract_MenuPageByRoleIDAndMenuID SP是用来获取页面名称和路径,
Extract_CssNameForMenuByMenuIDAndPageName SP用于设置活性类到所述第一立装置第一菜单。 跳这将帮助你.....它的工作代码..