كيف نقوم بتصميم Dynamic Menu و التي تعتمد على Database
أولا علينا تصميم الDatabase المطلوبة عن طريق هذا الكود الخاص ب SQL Server 2008
CREATE TABLE [dbo].[Menu](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](50) NOT NULL,
[description] [nvarchar](255) NULL,
[link] [nvarchar](100) NULL,
[menuId] [int] NULL,
CONSTRAINT [PK_Menu] PRIMARY KEY CLUSTERED
(
[id] 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 PROCEDURE [dbo].[MenuSelectAll]
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE @Err Int
SELECT * FROM Menu
SET @Err = @@ERROR
return @Err
END
GO
/****** Object: ForeignKey [FK_Menu_Menu] Script Date: 03/25/2011 20:00:10 ******/
ALTER TABLE [dbo].[Menu] WITH CHECK ADD CONSTRAINT [FK_Menu_Menu] FOREIGN KEY([menuId])
REFERENCES [dbo].[Menu] ([id])
GO
ALTER TABLE [dbo].[Menu] CHECK CONSTRAINT [FK_Menu_Menu]
GOو الذي نتيجته هذا Diagram
و كما نرى قمنا بتصميم جدول من أجل معلومات ال Menu
و علاقة SelfJoin التي نراها في الصورة هي من أجل Category -> SubCategory للقائمة التي نريد تصميمها
و نرى هذا من المدخلات للقائمة و التي هي تعبئة عشوائية فقط من أجل الدرس:
و نرى هنا NEWS لها أولاد و هم Local و International حيث نرى هذا من خلال MenuId و التي هي ForeignKey للعلاقة التي بين ID و MENUID (التي تشكل أب و أولاد)
و نراها في النتيجة النهائية:
حيث نجد News و يصدر عنها Local و International
و الآن لدينا Stored Procedure داخل الكود الذي في الأعلى لإحضار المعلومات من ال Table
و نأتي الآن لكود ASP.Net و الذي أستخدم فيه لغة CSharp
علينا الآن كتابة Method لإحضار المعلومات و إستخدام Store Procedure التي كتبت في الأعلى
و ها هو كود ال Method
private DataSet menuDataSelectAll()
{
DataSet data = null;
using (SqlConnection connection = new SqlConnection())
{
try
{
connection.ConnectionString = ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString;
using (SqlCommand command = new SqlCommand("MenuSelectAll", connection))
{
command.CommandType = CommandType.StoredProcedure;
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
connection.Open();
data = new DataSet();
adapter.Fill(data);
data.Relations.Add(new DataRelation("MenuFK", data.Tables[0].Columns["id"], data.Tables[0].Columns["menuId"], false));
}
}
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
finally
{
if (connection != null)
{
connection.Close();
}
}
}
return data;
}و الأهم هنا هو تحديدنا DataRelation في ال DataSet
data.Relations.Add(new DataRelation("MenuFK", data.Tables[0].Columns["id"], data.Tables[0].Columns["menuId"], false));و تأتي أهمية هذا الكود لإحضار أولاد كل Category رئيسية مثل News التي تأتينا بLocal و International
و الآن كود تعبئة ال Menu
private void fillMenu(DataSet data)
{
foreach (DataRow dr in data.Tables[0].Rows)
{
if (dr["MenuId"] == DBNull.Value)
{
fillMenuItem(dr, null);
}
}
}
private void fillMenuItem(DataRow dr, MenuItem mi)
{
MenuItem child = new MenuItem(dr["name"].ToString(), null, null, dr["link"] == DBNull.Value ? null : dr["link"].ToString());
if (mi == null)
{
mainMenu.Items.Add(child);
}
else
{
mi.ChildItems.Add(child);
}
foreach (DataRow drChild in dr.GetChildRows("MenuFK"))
{
fillMenuItem(drChild, child);
}
}و هنا في هذا الكود نقوم بأخذ كل Category من نوع Parent أي أب و التي تكون من دون أب لها و نرى هذا عندما تكون MenuId فارغة أي NULL
ثم ننادي ال Method الثاني التي تأتي بالأولاد و تعبئهم في MenuItem الخاص بالأب
و نرى النتيجة النهائية هنا:
ملفات المشروع بإستخدام Microsoft Visual Web Developer 2010 Express
