asp.net Dynamic Data Site with own MetaData - asp.net

I'm searching info about configuring own MetaData in asp.NET Dynamic Site.
For example. I have a table in MS Sql Server with structure shown below:
CREATE TABLE [dbo].[someTable](
[id] [int] NOT NULL,
[pname] [nvarchar](20) NULL,
[FullName] [nvarchar](50) NULL,
[age] [int] NULL)
and I there are 2 Ms Sql tables (I've created), sysTables and sysColumns.
sysTables:
ID sysTableName TableName TableDescription
1 | someTable |Persons |All Data about Persons in system
sysColumns:
ID TableName sysColumnName ColumnName ColumnDesc ColumnType MUnit
1 |someTable | sometable_pname| Name | Persona Name(ex. John)| nvarchar(20) | null
2 |someTable | sometable_Fullname| Full Name | Persona Name(ex. John Black)| nvarchar(50) | null
3 |someTable | sometable_age| age | Person age| int | null
I want that, in Details/Edit/Insert/List/ListDetails pages use as MetaData sysColumns and sysTableData. Because, for ex. in DetailsPage fullName, it is not beatiful as Full Name .
someIdea, is it possible?
thanks
Updated::
In List Page to display data from sysTables (metaData table) I've modified <h2 class="DDSubHeader"><%= tableName%></h2>.
public string tableName;
protected void Page_Init(object sender, EventArgs e)
{
table = DynamicDataRouteHandler.GetRequestMetaTable(Context);
//added by me
uqsikDataContext sd=new uqsikDataContext();
tableName = sd.sysTables.Where(n => n.sysTableName == table.DisplayName).FirstOrDefault().TableName;
//end
GridView1.SetMetaTable(table, table.GetColumnValuesFromRoute(Context));
GridDataSource.EntityTypeName = table.EntityType.AssemblyQualifiedName;
if (table.EntityType != table.RootEntityType)
{
GridQueryExtender.Expressions.Add(new OfTypeExpression(table.EntityType));
}
}
so, what about sysColums? How can I get Data from my sysColumns table?

In a word, yes, it is possible. However, I do not believe this is a good idea. What you are really talking about is storing presentation data in your database, when really the best place to put this is in your aspx pages themselves. That being said, if you want to store data dictionary type information in your DB, I'd recommend making use of the built in sys.tables, sys.columns, and sys.types views that are built into MS SQL Server, and adding a table called ObjectDescriptions to store the display name and type.
create table ObjectDescriptions (
object_id int not null,
column_id null, --leave this column null if the record describes the table itself
ObjectDisplayName nvarchar(20),
ObjectDescription nvarchar(200)
);
Then, you could create a view based on object ID to retrieve the meta data of your table, and either directly bind or dynamically populate your asp.net FormView.
create view TableData as
select
t.name as table_name
,td.ObjectDisplayName as table_display_name
,td.ObjectDescription as table_description
,c.name as column_name
,cd.ObjectDisplayName as column_display_name
,cd.ObjectDescription as column_description
,c.column_id
,ty.name as [type_name]
,c.max_length
,c.scale
,c.[precision]
from sys.tables t
left join ObjectDescriptions td on td.object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
left join ObjectDescriptions cd on cd.column_id = c.column_id and cd.object_id = c.object_id
join sys.types ty on c.user_type_id = ty.user_type_id
EDIT:
You can then leverage this view in your ASP code by writing a class that holds your meta data about a single table, and writing a method in your DAL to retrieve an instance of this class based on object or table name. When you populate your page, the page could retrieve both the record you are looking for, as well as the table's meta-data, and bind that meta data to either grid headers (in list view) or to individual label's accompanying text boxes in single record mode.

I've found useful article, than can be used for solution my problem

Related

Except the name of table what property can use to differentiate these tables

I have a database which contains many tables and these tables can be added or removedd any time.So I give each of them a different name like Table1,Table2,...
but it's uncomfortable to use these table because sometime I forget what infomation was stored in Table1
So I want something to differentiate these all tables, some property that I can be specified when I create a table and I can use to access a specific table when I need to fetch informations from that table
As one comment says, you could create a table for notes on the other tables:
CREATE TABLE notes (
id INT AUTO_INCREMENT,
table_name VARCHAR(64),
note VARCHAR(255),
PRIMARY KEY (id)
);
By the way, MySQL (but not SQLite) allows comments on the table itself:
CREATE TABLE table1 (
id INT AUTO_INCREMENT,
val INT,
PRIMARY KEY (id)
) COMMENT = 'Table of stuff';
-- Show the comment
SHOW TABLE STATUS WHERE NAME='table1';
-- Just show names and comments
SELECT `TABLE_NAME`, `TABLE_COMMENT`
FROM information_schema.tables
WHERE table_schema = DATABASE();

How to autogenerate the username with specific string?

I am using asp.net2008 and MY SQL.
I want to auto-generate the value for the field username with the format as
"SISI001", "SISI002",
etc. in SQL whenever the new record is going to inserted.
How can i do it?
What can be the SQL query ?
Thanks.
Add a column with auto increment integer data type
Then get the maximum value of that column in the table using "Max()" function and assign the value to a integer variable (let the variable be 'x').
After that
string userid = "SISI";
x=x+1;
string count = new string('0',6-x.ToString().length);
userid=userid+count+x.ToString();
Use userid as your username
Hope It Helps. Good Luck.
PLAN A>
You need to keep a table (keys) that contains the last numeric ID generated for various entities. This case the entity is "user". So the table will contain two cols viz. entity varchar(100) and lastid int.
You can then have a function written that will receive the entity name and return the incremented ID. Use this ID concatenated with the string component "SISI" to be passed to MySQL for insertion to the database.
Following is the MySQL Table tblkeys:
CREATE TABLE `tblkeys` (
`entity` varchar(100) NOT NULL,
`lastid` int(11) NOT NULL,
PRIMARY KEY (`entity`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The MySQL Function:
DELIMITER $$
CREATE FUNCTION `getkey`( ps_entity VARCHAR(100)) RETURNS INT(11)
BEGIN
DECLARE ll_lastid INT;
UPDATE tblkeys SET lastid = lastid+1 WHERE tblkeys.entity = ps_entity;
SELECT tblkeys.lastid INTO ll_lastid FROM tblkeys WHERE tblkeys.entity = ps_entity;
RETURN ll_lastid;
END$$
DELIMITER ;
The sample function call:
SELECT getkey('user')
Sample Insert command:
insert into users(username, password) values ('SISI'+getkey('user'), '$password')
Plan B>
This way the ID will be a bit larger but will not require any extra table. Use the following SQL to get a new unique ID:
SELECT ROUND(NOW() + 0)
You can pass it as part of the insert command and concatenate it with the string component of "SISI".
I am not an asp.net developer but i can help you
You can do something like this...
create a sequence in your mysql database as-
CREATE SEQUENCE "Database_name"."SEQUENCE1" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 001 START WITH 21 CACHE 20 NOORDER NOCYCLE ;
and then while inserting use this query-----
insert into testing (userName) values(concat('SISI', sequence1.nextval))
may it help you in your doubt...
Try this:
CREATE TABLE Users (
IDs int NOT NULL IDENTITY (1, 1),
USERNAME AS 'SISI' + RIGHT('000000000' + CAST(IDs as varchar(10)), 4), --//getting uniqueness of IDs field
Address varchar(150)
)
(not tested)

shopping cart database design and the flow of putting the orders into the tables

I'm creating a database in SQL Server 2005 to store orders taken.
table [customers] : customer detail table primary key is the customer_ID which will be an identity autoincremental
table [orders] : holds 3 columns, [orderid](which is also the pk),[product_id],[quantity]
table [linking] : holds 2 columns, [customerid](as foreign key), [orderid](foreign key as well)
ordering flow :
when customer checked out, the customer's detail will be stored to table[customers] in which a unique customer_ID will be generated.
next, using that customer_ID, the products in the shopping cart will be stored into table[orders] .
now, the problem is: how do i retrieve the auto_generated customer_ID from the table[customers]? assuming that a lot of users are checking out at the same time? After inserting the customer's detail into the table[customer], I have to use the customer_ID in the table[linking] to pair up with the orderid.
Write a few SQL stored procedures to do this work for you. You can call this from your web application's code using ADO.NET.
Call proc CreateCustomer. It creates your CustomerID.
Call proc CreateOrderForCust.
CREATE PROC CreateCustomer
#Name varchar(100),
#Address varchar(100)
AS
DECLARE #CustomerID int;
INSERT INTO CUSTOMER([Name],[Addr]) VALUES (#Name, #Addr);
SELECT #CustomerID = SCOPE_IDENTITY();
RETURN #CustomerID;
...
CREATE PROC CreateOrderForCust
#CustomerID int,
#SKU int,
#Qty int
AS
.....

Inserting into two tables and Identity_Scope()

I am building a forum and I have two tables:
Threads
-------
ThreadID
UsersID
Date
ThreadTitle
ThreadParagraph
ThreadClosed
Topics
-----
TopicsID
Theme
Topics
Date
The ThreadID is connected to the users table with a primary key:
Topics.TopicsID(PK)==Threads.TopicID(FK)
First i insert into the Topics table and then to the Threads table. My goal is to obtain the ID of Topics.TopicID with Identity_Scope() and pass it to the second insert which is Threads.TopicID
Here is what i have done, but i am not sure if it is correct:
StringBuilder insertCommand = new StringBuilder();
insertCommand.Append("DECLARE #TopicsID int");
insertCommand.Append("INSERT INTO Topics(Theme,Topics,Date)");
insertCommand.Append("VALUES('#topic,#subTopic,GETDATE()')");
insertCommand.Append("SET #TopicsID = SCOPE_IDENTITY()");
insertCommand.Append("INSERT INTO Threads(UsersID,TopicsID,Date,ThreadTitle,ThreadParagraph,ThreadClosed)");
insertCommand.Append("VALUES('#uniqueIdentifier,#TopicsID,GETDATE(),#questionTitle,#questionParagraph,0')");
I have got all the otehr parameters obtained from the controls the users presses or feeds information into, so dont worry about them. All i am worried about is passing the same TopicID from the Topic table to Thread table (Column name: TopicID).
Both Magnus & Damien_The_Unbeliever are right - you have few syntax errors (or typos). Correct insert command should be something like
insertCommand.Append(#"
DECLARE #TopicSID int
INSERT INTO Topics(Theme,Topics,Date)
VALUES(#topic,#subTopic,GETDATE())
SET #TopicSID = SCOPE_IDENTITY()
INSERT INTO Threads(UsersID,TopicsID,Date,ThreadTitle,ThreadParagraph,ThreadClosed)
VALUES(#uniqueIdentifier,#TopicSID ,GETDATE(),#questionTitle,#questionParagraph,0)
");

Numbering comments in ASP.NET and SQL Server

I've just thought about best way to store comments in database with appropriate numbers according to the article.
The idea is to store comments with composite primary key (commentId, articleId) where commentId is generated according to the given articleId. The system of generating should has same principle as IDENTITY generated columns in SQL Server, because if someone delete the comment, the number will be never used again. I guess there is not any functionality in Microsoft SQL Server to do that with composite PK, so I am asking about some replacement for this solution.
First thought was to use transaction to get MAX(commentId) + 1, but I am looking for something more abstract (maybe INSTEAD OF trigger), something that could be used for example in LINQ with no knowledge of the background, just insert to the appropriate table all required values (so no commentId) and save it.
I would use an autogenerated identity column for the commentId and have it be the primary key alone. I'd create an index on the articleId for look ups. I would also have createdDate column that is autopopulated with the current date on insertion -- mark it as db generated and readonly in LINQ so it doesn't require or try to insert/update the value. To get a numbering -- if showing them by date isn't enough -- I'd order by createdDate inversed and assign a numeric value in the select using Row_Number() or a numbering on the client side.
I would use an identity column as the key for the comments, why do you need a numbering for the comments stored in the database?
Thank you for responses, I wanted something with numbered comments because of referencing in the text of comments. I did not want to make reaction by names, sometimes one person reacts more times, so with this system, I will know to which one the person is replying.
So today I made up this INSTEAD OF INSERT trigger:
CREATE TRIGGER InsertComments ON Comments
INSTEAD OF INSERT
AS
DECLARE #Inserted TABLE
(
ArticleId INT NOT NULL,
UserId INT NOT NULL,
CommentDate DATETIME NOT NULL,
Content NVARCHAR(1000) NOT NULL,
RowNumber INT NOT NULL
)
INSERT INTO #Inserted
SELECT ArticleId, UserId, CommentDate, Content, ROW_NUMBER() OVER (ORDER BY CommentDate) AS RowNumber
FROM INSERTED
DECLARE #NumberOfRows INT = (SELECT COUNT(*) FROM #Inserted)
DECLARE #i INT = 1
WHILE (#i <= #NumberOfRows)
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
DECLARE #CommentId INT = (SELECT ISNULL(MAX(CommentId), 0)
FROM Comments WHERE ArticleId = (SELECT ArticleId
FROM #Inserted WHERE RowNumber = #i)) + 1
INSERT INTO Comments(CommentId, ArticleId, UserId, CommentDate, Content)
SELECT #CommentId, ArticleId, UserId, CommentDate, Content
FROM #Inserted WHERE RowNumber = #i
COMMIT
SET #i = #i + 1
END
I know this is not the perfect solution, but it works exactly how I needed. If any of you has some comments, I'll be happy to read them.

Resources