Saturday, 31 December 2011
Sunday, 25 December 2011
Comprendre la notion d'application role sous Sql Server en 05 minutes
Une application rôle est au même titre que les database role une notion de la base de données qui va permettre de faciliter la gestion des permissions au niveau des objets depuis un point de vue applicatif.
Les exemples qui suivent sont utilisés dans le contexte d'AdventureWorks
Pour créer une application role :
Intéressant non !
Les exemples qui suivent sont utilisés dans le contexte d'AdventureWorks
Pour créer une application role :
create application role MonRole with password='MonMotdePasse' , DEFAULT_SCHEMA = Production
Pour vous donner un peu plus d'approche sur la notion, executez la commande suivante :
L'interêt d'utiliser une application rôleselect * from sys.database_principals
- Supposons que dans une société, le département HR accède la base via une application Web1, le département TRAVEL l'accède via un client WPF et le département SERVICE l'accède à partir d'une application WEB2. Chaque membre de ses départements est supposé n'avoir droit qu'aux objects qui les concernent dans la base, et qu'il ne doit pas avoir accès directement à la base ( dans ce sens, pensez sur le fait que sur un client WPF qui s'execute sur le poste de l'utilisateur, l'authentification peut etre les 'credentials' de l'utilisateur lui même ).
Dans ces conditions, il s'avère que le choix de la stratégie d'une application rôle est le moindre effort et la moins couteuse pour le département informatique.
Comment le mettre en oeuvre ?
Dans ce sens, il faut créer une application role pour chaque département (cf plus haut).
create application role HR_Departement_Role with password='MonMotdePasse' , DEFAULT_SCHEMA = Production
Il faut noter qu'une application rôle ne contiendra pas d'utilisateurs.
Dans le code application de l'application web destinée aux membres du HR par exemple
- le code est laissé tres rudimentaire pour se concentrer au contexte principal de l'article
Si je l'execute, alors j'aurai l'erreur
L'erreur montre qu'un select n'est pas permis pour celui sous lequel s'execute le contexte courant.
Celui est normal car une fois que nous ayions fait appel à l'activation de l'application role dans notre code (sp_setapprole), il faut que celui ci dispose de suffisamment de privilèges pour faire la requête select * from Product
Pour corriger
grant select on schema::Production to HR_Departement_Role
Cette commande attribue le droit de faire un select sur le schéma Production (sous lequel appartient la table Product) pour l'application role HR
Après relance, la requête retourne bien la liste voulue.
Ainsi nous avons vu qu'il nous a fallu :
- crèer les application roles et leur droit au niveau de la base
- ajouter 02 lignes de codes pour le changement de contexte d’exécution au niveau du code, et ce totalement indépendant de l'implémentation existante.
Saturday, 24 December 2011
Xmas Day
I wish you all and your family a Merry Christmas
Je vous souhaite un joyeux noel
Comprendre le type decimal sous SQL Server en moins de 30 secondes
No comment :
decimal(4,2) veut dire le nombre est composé de 4 chiffres au total dont 2 situés après la virgule.
Ceci étant la valeur peut varier de 00,00 jusqu'à 99,99 en valeur absolue
decimal(4,2) veut dire le nombre est composé de 4 chiffres au total dont 2 situés après la virgule.
Ceci étant la valeur peut varier de 00,00 jusqu'à 99,99 en valeur absolue
Thursday, 8 December 2011
Entity Framework managing a many-to-many relationship
In this article, i'll will show how to manage a many-to-many relationship in Entity Framework 4.
First of all, lets's see the representation of the basic model, from power designer :
Here we have two entities named ENTITY_1 and ENTITY_2. One instance of ENTITY_1 may have 1 or more instance of ENTITY_2 and vice-versa. One instance of ENTITY_1 (ENTITY_2) is identified uniquely by a property called ENTITY1_ID (ENTITY2_ID).
At the PMD, we have a physical representation like this
And the corresponding SQL Server Diagram :
So, the question is how to link entries in ENTITY_1 with entries in ENTITY_2 by filling the association table RELATION_1. In TSQL, we need to insert explicitly this combination by doing something like :
INSERT INTO [RELATION_1] VALUES (.......)
This concept doesn't exist explicitly in EF as seen in the generated diagram :
The RELATION_1 table, which exist for real in the sys.tables of the current database, is not mapped as a real entity at the EF level.
After running this code, take a look at all involved tables :
As we can see, the table RELATION_1 is auto filled with the corresponding association.
Consider the case where the association entity has an attribute named value :
The generated edmx will show a concrete entity named relation_1 having an attribute named value:
As we can see, things become more explicit because EF has created a new entity mapping the RELATION_1 table.
Inserting becomes more easier as show :
First of all, lets's see the representation of the basic model, from power designer :
Here we have two entities named ENTITY_1 and ENTITY_2. One instance of ENTITY_1 may have 1 or more instance of ENTITY_2 and vice-versa. One instance of ENTITY_1 (ENTITY_2) is identified uniquely by a property called ENTITY1_ID (ENTITY2_ID).
At the PMD, we have a physical representation like this
And the corresponding SQL Server Diagram :
So, the question is how to link entries in ENTITY_1 with entries in ENTITY_2 by filling the association table RELATION_1. In TSQL, we need to insert explicitly this combination by doing something like :
INSERT INTO [RELATION_1] VALUES (.......)
This concept doesn't exist explicitly in EF as seen in the generated diagram :
The RELATION_1 table, which exist for real in the sys.tables of the current database, is not mapped as a real entity at the EF level.
After running this code, take a look at all involved tables :
As we can see, the table RELATION_1 is auto filled with the corresponding association.
Consider the case where the association entity has an attribute named value :
The generated edmx will show a concrete entity named relation_1 having an attribute named value:
As we can see, things become more explicit because EF has created a new entity mapping the RELATION_1 table.
Inserting becomes more easier as show :
Sunday, 4 December 2011
SQL Server - une bonne pratique pour la déclaration de CONSTRAINT - French Version
Un objet d'une base de données SQL Server peut être relié à plusieurs contraintes (clé primaire, clé étrangère, contrôle de valeurs, ...). Ces contraintes peuvent être définis soit à la création de l'objet lui-même soit plus tard par une modification depuis la commande ALTER.
J'ai vu souvent vu des scripts de création de contraintes de ce type :
CREATE TABLE [TIPS_05] (ID INT, AGE INT CHECK( AGE > 0))
Malgré le fait que le script passe en exécution, il importe de noter que SQL Server va créer implicitement une contrainte pour 'CHECK(AGE > 0)'
Problématique :
- Supposons que l'entreprise ait une norme établie pour le nommage des objects SQL créés ( y compris les contraintes).
- A un certain moment, une contrainte peut faire l'objet d'une désactivation temporaire, par exemple pour une modification exceptionnelle d'une valeur de la colonne AGE - pour le cas de personne dont l'age n'est pas connue.
La pratique ci-dessus ne vas pas à l'encontre de ce principe. En effet, par principe, la recommandation est de désactivée temporairement la contrainte avant l'insertion et de le remettre une fois les mises à jour effectuées.
Dans le cas présent, nous ne pouvons pas 'deviner à priori' le nom de la contrainte car c'est SQL qui l'a attribué automatiquement
Néanmoins, nous pouvons la voir en executant la requête suivante :
select * from sys.tables where name = 'TIPS_05'
Ici le nom de la contrainte a été défini explicitement, d'une manière plus facile à deviner selon les conventions de nommages établies.
J'ai vu souvent vu des scripts de création de contraintes de ce type :
CREATE TABLE [TIPS_05] (ID INT, AGE INT CHECK( AGE > 0))
Malgré le fait que le script passe en exécution, il importe de noter que SQL Server va créer implicitement une contrainte pour 'CHECK(AGE > 0)'
Problématique :
- Supposons que l'entreprise ait une norme établie pour le nommage des objects SQL créés ( y compris les contraintes).
- A un certain moment, une contrainte peut faire l'objet d'une désactivation temporaire, par exemple pour une modification exceptionnelle d'une valeur de la colonne AGE - pour le cas de personne dont l'age n'est pas connue.
La pratique ci-dessus ne vas pas à l'encontre de ce principe. En effet, par principe, la recommandation est de désactivée temporairement la contrainte avant l'insertion et de le remettre une fois les mises à jour effectuées.
Dans le cas présent, nous ne pouvons pas 'deviner à priori' le nom de la contrainte car c'est SQL qui l'a attribué automatiquement
Néanmoins, nous pouvons la voir en executant la requête suivante :
select * from sys.tables where name = 'TIPS_05'
puis par
SELECT * FROM sys.objects where type = 'C' and parent_object_id = 759673754Nous pouvons alors voir que le nom de la contrainte est 'CK__TIPS_05__AGE__2E3BD7D3'
Nous pouvons alors provisoirement la desactiver par
ALTER TABLE [TIPS_05] NOCHECK CONSTRAINT CK__TIPS_05__AGE__2E3BD7D3
Puis insérer des valeurs non autorisées
INSERT INTO [TIPS_05] VALUES (3,-30)
Puis réactiver la contrainte
ALTER TABLE [TIPS_05] CHECK CONSTRAINT CK__TIPS_05__AGE__2E3BD7D3
Il était alors plus simple et plus pratique de déclarer la contrainte comme ceci :
-à la rigueur :
CREATE TABLE [TIPS_05] (ID INT, AGE INT CONSTRAINT CK_AGE CHECK( AGE > 0))
- idéalement :
CREATE TABLE [TIPS_05] (ID INT, AGE INT);
GO
ALTER TABLE [TIPS_05] ADD CONSTRAINT CK_AGE CHECK (AGE > 0);
ALTER TABLE [TIPS_05] ADD CONSTRAINT CK_AGE CHECK (AGE > 0);
GO
Ici le nom de la contrainte a été défini explicitement, d'une manière plus facile à deviner selon les conventions de nommages établies.
Friday, 2 December 2011
JQuery Autocomplete in an ASP.NET page - The quick howto step by step
Today, i have the need to build quickly a lightweight web control using an 'autocomplete' style. Severals products in the market exist for this implementation :
- ultracombo from infragistics
- autocomplete for ajaxcontroltoolkit
- a jquery plugin as : autocomplete . it will be shown in this post.
For this purpose, you need to download jquery autocomplete plugin available at http://jqueryui.com/download
1- Deselect all components
2- Select only the autocomplete plugins
3- Click on the download link on the rigth pane of the page ( not display in the screenshot).
It will package all the scripts, samples pages etc... refering this plugin.
In the visual studio, create a web application projet, add folder and files as shown in the screeshot
In this screeshot :
1- Create the folder 'script' and put all js script from the dowloaded package above.
Those script are needed to run the autocomplete component
2- Create the folder 'style' and put all css from the download package
Stylesheet to be used
3- Create an aspx page named 'Json'
The main page
4- Create an Handler1.ashx ( Generic Handler ) from Visual Studio Add item.
An handler to handle all ajax requests, process request in server side and return the datas to clien.
In the page Json.aspx :
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<link rel="stylesheet" href="../style/jquery.ui.all.css">
<script type="text/javascript" src="../script/jquery-1.6.2.js"></script>
<script type="text/javascript" src="../script/jquery.ui.core.js"></script>
<script type="text/javascript" src="../script/jquery.ui.widget.js"></script>
<script type="text/javascript" src="../script/jquery.ui.position.js"></script>
<script type="text/javascript" src="../script/jquery.ui.autocomplete.js"></script>
<script type="text/javascript">
$(function() {
$(".Form_Product").autocomplete({
source: "Handler1.ashx",
minLength: 2,
select: function(event, ui) {
}
});
});
</script>
</head>
<body>
<form id="Form" runat="server">
<div class="ui-widget">
<label for="Item">Products : </label>
<asp:TextBox id="Form_Product" class="Form_Product" runat="server" />
</div>
<asp:HiddenField ID="Form_HiddenValue" runat="server" />
</form>
</body>
</html>
In the source parameter, i've define the handler.ashx to where the request is sended.
The minLength parameter means that the request is fired once the user type 2 caracters in the input.
The select parameter is used to fire action on client side once the server response is received
The Form_Product textbox is the main input linked to the autocomplete feature.
Notice that I've defined a class named 'Form_Product' into it.
If we look at the second line of the javascript code, i've used a jQuery selector
Using a class selector $(".Form_Product") is more powerfull than using an Id selector $("#Form_Product") in the way that if the Textbox is embedded into a Master Page, the Id generated by asp.net is changed automatically depending on the hierachical level of the contentplaceholder. The class attribut of the Textbox will always be the same.
The div class="ui-widget" is not mandatory, I've put it for having a specific style.
The Form_HiddenValue is optional, it is used to store the content of the selected item if the page has to support a postback. I will not described that in this post.
That's all of the modification that we need to do in the aspx file.
Go to the code behin of the handle1.ashx and paste the code
Interpretation :
The autocomplete automatically maps the value property of the json string. In the screen below, the json format returned by the handler.
The textBox is filled by this value property.
How to access the Brand property ?
In the function select body :
<script type="text/javascript">
$(function() {
$(".Form_Product").autocomplete({
source: "Handler1.ashx",
minLength: 2,
select: function(event, ui) {
//HERE PUT
alert(ui.item.id);
alert(ui.item.value);
alert(ui.item.Brand); //Magic isn't it ???
}
});
});
The strength :This implementation suits very well in an mvc or mvvm implementation. the viewmodel return only the representation of the business and javascript will do the rest in the view layer.
Hope that this post was helpfull for you.
- ultracombo from infragistics
- autocomplete for ajaxcontroltoolkit
- a jquery plugin as : autocomplete . it will be shown in this post.
For this purpose, you need to download jquery autocomplete plugin available at http://jqueryui.com/download
1- Deselect all components
2- Select only the autocomplete plugins
3- Click on the download link on the rigth pane of the page ( not display in the screenshot).
It will package all the scripts, samples pages etc... refering this plugin.
In the visual studio, create a web application projet, add folder and files as shown in the screeshot
In this screeshot :
1- Create the folder 'script' and put all js script from the dowloaded package above.
Those script are needed to run the autocomplete component
2- Create the folder 'style' and put all css from the download package
Stylesheet to be used
3- Create an aspx page named 'Json'
The main page
4- Create an Handler1.ashx ( Generic Handler ) from Visual Studio Add item.
An handler to handle all ajax requests, process request in server side and return the datas to clien.
In the page Json.aspx :
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<link rel="stylesheet" href="../style/jquery.ui.all.css">
<script type="text/javascript" src="../script/jquery-1.6.2.js"></script>
<script type="text/javascript" src="../script/jquery.ui.core.js"></script>
<script type="text/javascript" src="../script/jquery.ui.widget.js"></script>
<script type="text/javascript" src="../script/jquery.ui.position.js"></script>
<script type="text/javascript" src="../script/jquery.ui.autocomplete.js"></script>
<script type="text/javascript">
$(function() {
$(".Form_Product").autocomplete({
source: "Handler1.ashx",
minLength: 2,
select: function(event, ui) {
}
});
});
</script>
</head>
<body>
<form id="Form" runat="server">
<div class="ui-widget">
<label for="Item">Products : </label>
<asp:TextBox id="Form_Product" class="Form_Product" runat="server" />
</div>
<asp:HiddenField ID="Form_HiddenValue" runat="server" />
</form>
</body>
</html>
In the source parameter, i've define the handler.ashx to where the request is sended.
The minLength parameter means that the request is fired once the user type 2 caracters in the input.
The select parameter is used to fire action on client side once the server response is received
The Form_Product textbox is the main input linked to the autocomplete feature.
Notice that I've defined a class named 'Form_Product' into it.
If we look at the second line of the javascript code, i've used a jQuery selector
Using a class selector $(".Form_Product") is more powerfull than using an Id selector $("#Form_Product") in the way that if the Textbox is embedded into a Master Page, the Id generated by asp.net is changed automatically depending on the hierachical level of the contentplaceholder. The class attribut of the Textbox will always be the same.
The div class="ui-widget" is not mandatory, I've put it for having a specific style.
The Form_HiddenValue is optional, it is used to store the content of the selected item if the page has to support a postback. I will not described that in this post.
That's all of the modification that we need to do in the aspx file.
Go to the code behin of the handle1.ashx and paste the code
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json"; //since i will use a json format as //response, it need to set the contentType to application/json.
context.Response.ContentEncoding = System.Text.Encoding.UTF8;//will use UTF8 //encoding - optional
Collection<Data> s = new Collection<Data>();//here I've create a class named Data - we will //see it later in this post
// Add some value in the collection, noticed the property id and value of the object. They are //required to be set to make the auto mapping of autocomplete plugin. If omitted, the autocomplete //failed
s.Add(new Data { id = "1", value = "987", Brand = "Apple" });
s.Add(new Data { id = "2", value = "98765", Brand = "Windows" });
s.Add(new Data { id = "3", value = "9876534", Brand = "Android" });
// Using of the javascriptSerializer to transform the collection to json format - the input form the //textbox is retrieved by context.Request.QueryString["term"].Here I've used a Linq to filter the //hardcoded collected by the StartWith method.//here is the Data class. Notice the id, value property. You can omit them in this class and use an anonymous type in the linq query but it's beyond of the scope.Also notice that the class is marked as Serializable to allow the json serialization
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
context.Response.Write(jsonSerializer.Serialize(s.Where(v => v.value.StartsWith(context.Request.QueryString["term"])).ToList()));
}
public bool IsReusable
{
get
{
return false;
}
}
}
[Serializable]Now the test
public class Data
{
public String id { get; set; }
public String value { get; set; }
public String Brand { get; set; }
}
Interpretation :
The autocomplete automatically maps the value property of the json string. In the screen below, the json format returned by the handler.
The textBox is filled by this value property.
How to access the Brand property ?
In the function select body :
<script type="text/javascript">
$(function() {
$(".Form_Product").autocomplete({
source: "Handler1.ashx",
minLength: 2,
select: function(event, ui) {
//HERE PUT
alert(ui.item.id);
alert(ui.item.value);
alert(ui.item.Brand); //Magic isn't it ???
}
});
});
The strength :This implementation suits very well in an mvc or mvvm implementation. the viewmodel return only the representation of the business and javascript will do the rest in the view layer.
Hope that this post was helpfull for you.
Subscribe to:
Posts (Atom)