2010-12-03 40 views
0

J'ai le même modèle de données sur un tas de serveurs différents. Je veux créer dynamiquement une chaîne de connexion en fonction de qui est mon utilisateur et de ce qu'il fait.Silverlight Entity Framework Chaîne de connexion dynamique

Mes utilisateurs peuvent avoir plusieurs bases de données sur plusieurs serveurs. J'ai besoin d'un moyen propre pour construire une chaîne connectoin quand je crée mon DomainService.

Je vois que le DomainService a un override (hérité de LinqToEntitiesDomainService) appelé CreateObjectContext() qui me permettrait de définir toute chaîne de connexion que je veux, puis retourner la nouvelle entité et la vie est bonne. Le problème est, le CreateObjectContext() est appelé après le constructeur, donc je ne peux pas définir une chaîne via une méthode invoke. En outre, j'ai essayé de créer un nouveau constructeur paramétré sur le DomainService, mais il n'est jamais copié sur le DomainContext sur le client. Le CreateObjectContext() fonctionnerait très bien si j'étais capable de tirer ma chaîne de connexion, mais comme je dois utiliser les données du client pour déterminer quelle base de données se connecter, cela ne fonctionnera évidemment pas.

Plus j'y pense, plus je pense qu'un constructeur personnalisé est exactement ce dont j'ai besoin - je n'arrive pas à comprendre comment le faire.

Qu'est-ce qui me manque?

+0

Qu'en est-il de WCF Data Services? – vorrtex

Répondre

4

J'ai trouvé une solution. Pour ceux qui sont intéressés, le voici:

Cela ressemble un peu à un hack, mais c'est la seule solution que je pourrais trouver. Merci à Sally Xu sur forums.silverlight.net pour les idées.

Étant donné que chacun de mes utilisateurs peut avoir plusieurs bases de données sur plusieurs serveurs, je devais trouver un moyen de créer la ConnectionString avant que le DomainService soit utilisé la première fois. Chaque fois que l'utilisateur sélectionne un nouveau projet à partir de l'interface utilisateur, je mis un cookie comme celui-ci:

private void SetCookie(string cookieName, string cookieValue) 
{ 
    DateTime expireDate = DateTime.Now + TimeSpan.FromDays(1); 
    string newCookie = cookieName + "=" + cookieValue + ";expires=" + expireDate.ToString("R"); 
    HtmlPage.Document.SetProperty("cookie", newCookie); 
} 

Le cookieName est SelectedProjectId et le cookievalue est le projet actuellement sélectionné dans mon interface utilisateur.

Ensuite, je crée un nouveau DomainService comme d'habitude, mais je remplace CreateObjectContext(). Cette méthode est appelée la toute première fois que vous référencez votre objet DomainService. Mon override ressemble à ceci:

protected override ProjectEntities CreateObjectContext() 
{ 
    long projectId = -1; 
    StringBuilder connection; 
    if (System.Web.HttpContext.Current.Request.Cookies["SelectedProjectId"] != null) 
    { 
    projectId = Convert.ToInt64(System.Web.HttpContext.Current.Request.Cookies["SelectedProjectId"].Value); 
    } 
    else throw new Exception("Selected Project ID Exception"); // temporary 

    // Verify this user has access to the DB just in case it's spoofed 

    // Lookup project ID in my database to get the database name and server name 

    // Load template connection string found in web.config 
    // Replace the template holders for SERVER_NAME and DATABASE_NAME with above lookup values 

    return new ProjectEntities(MyDynamicConnectionString);  
} 

Encore une fois, cela est un peu hackish, mais ce fut la seule façon que je pouvais trouver pour créer dynamiquement une chaîne de connexion pour mes besoins. J'espère que cela aide quelqu'un d'autre ...