Saturday 31 December 2011

Bye Bye 2011 - Welcome 2012

Happy New Year 2012 to All - health - happiness - prosperity -  peace and unity to you and your familly

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 :
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 :
select * from sys.database_principals
L'interêt d'utiliser une application rôle
- 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.

Intéressant non !

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

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 :














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'




puis par 
SELECT * FROM sys.objects where type = 'C' and parent_object_id = 759673754



Nous 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);
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 


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.        
            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;
            }
        }
    }
//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 
    [Serializable]
    public class Data
    {
        public String id { get; set; }
        public String value { get; set; }
        public String Brand { get; set; }
    }
Now the test


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.