Forum Aux Questions (LINQ to SQL)

Mise à jour : November 2007

Les sections suivantes fournissent des réponses à quelques problèmes courants que vous êtes susceptible de rencontrer lors de l'implémentation de LINQ.

D'autres problèmes sont traités dans Dépannage (LINQ to SQL).

Impossible de se connecter

Q. Je ne peux pas me connecter à ma base de données.

R. Vérifiez que votre chaîne de connexion est correcte et que votre instance SQL Server s'exécute. Notez également que LINQ to SQL requiert l'activation du protocole Named Pipes. Pour plus d'informations, consultez Apprentissage par les procédures pas à pas (LINQ to SQL).

Modifications de la base de données perdues

Q. J'ai apporté à une modification à des données dans la base de données, mais lorsque j'exécute de nouveau mon application, cette modification a disparu.

R. Assurez-vous que vous appelez SubmitChanges pour enregistrer les résultats dans la base de données.

Connexion à la base de données : durée de l'ouverture

Q. Pendant combien de temps ma connexion à la base de données reste-t-elle ouverte ?

A. Une connexion reste généralement ouverte jusqu'à ce que vous utilisiez les résultats de la requête. Si vous prévoyez que le traitement de tous les résultats risque de prendre du temps et que vous n'êtes pas opposé à la mise en cache des résultats, appliquez ToList<TSource> à la requête. Dans les scénarios courants où chaque objet est traité une seule fois, le modèle de diffusion en continu est supérieur à la fois dans DataReader et LINQ to SQL.

Les détails exacts d'utilisation de la connexion dépendent des éléments suivants :

Mise à jour sans interrogation

Q. Est-ce que je peux mettre à jour des données de table sans interroger d'abord la base de données ?

R. Bien que LINQ to SQL ne comporte pas de commandes de mise à jour reposant sur un jeu, vous pouvez utiliser l'une des techniques suivantes pour effectuer une mise à jour sans exécuter de requête préalable :

  • Utilisez ExecuteCommand pour envoyer le code SQL.

  • Créez une nouvelle instance de l'objet et initialisez toutes les valeurs actuelles (champs) qui affectent la mise à jour. Puis attachez l'objet au DataContext à l'aide de Attach et modifiez le champ que vous souhaitez changer.

Résultats de requête inattendus

Q. Ma requête retourne des résultats inattendus. Comment vérifier ce qui se produit ?

R. LINQ to SQL fournit plusieurs outils permettant d'inspecter le code SQL qu'il génère. L'un des plus importants est Log. Pour plus d'informations, consultez Prise en charge du débogage (LINQ to SQL).

Résultats de procédure stockée inattendus

Q. J'ai une procédure stockée dont la valeur de retour est calculée par MAX(). Lorsque je fais glisser la procédure stockée vers la surface Concepteur O/R, la valeur de retour n'est pas correcte.

R. LINQ to SQL fournit deux manières de retourner des valeurs générées par la base de données au moyen de procédures stockées :

  • en nommant le résultat de sortie ;

  • en spécifiant explicitement un paramètre de sortie.

Un exemple de sortie incorrecte est fourni ci-dessous. LINQ to SQL ne pouvant pas mapper les résultats, il retourne toujours 0 :

create procedure proc2

as

begin

select max(i) from t where name like 'hello'

end

Un exemple de sortie correcte à l'aide d'un paramètre de sortie est fourni ci-dessous :

create procedure proc2

@result int OUTPUT

as

select @result = MAX(i) from t where name like 'hello'

go

Un exemple de sortie correcte à l'aide du nommage du résultat de sortie est fourni ci-dessous :

create procedure proc2

as

begin

select nax(i) AS MaxResult from t where name like 'hello'

end

Pour plus d'informations, consultez Personnalisation d'opérations à l'aide de procédures stockées (LINQ to SQL).

Erreurs de sérialisation

Q. Lorsque je tente d'effectuer une sérialisation, j'obtiens l'erreur suivante : "Le type 'System.Data.Linq.ChangeTracker+StandardChangeTracker' ... n'est pas marqué comme sérialisable.".

R. La génération de code dans LINQ to SQL prend en charge la sérialisation DataContractSerializer. Elle ne prend pas en charge XmlObjectSerializer ni BinaryFormatter. Pour plus d'informations, consultez Sérialisation (LINQ to SQL).

Plusieurs fichiers DBML

Q. Lorsque j'ai plusieurs fichiers DBML qui partagent des tables en commun, j'obtiens une erreur du compilateur.

R. Attribuez aux propriétés Context Namespace et Entity Namespace d'Concepteur Objet/Relationnel une valeur distincte pour chaque fichier DBML. Cette approche permet d'éliminer la collision de nom et d'espace de noms.

Éviter la définition explicite des valeurs générées par une base de données pour l'insertion ou la mise à jour

Q. J'ai une table de base de données comportant une colonne DateCreated qui a comme valeur par défaut SQL Getdate(). Lorsque j'essaie d'insérer un nouvel enregistrement à l'aide de LINQ to SQL, la valeur devient NULL. Il me semble qu'elle devrait être la valeur par défaut de la base de données.

R. LINQ to SQL gère automatiquement cette situation pour les colonnes identity (incrémentation automatique), rowguidcol (GUID généré par la base de données) et timestamp. Dans les autres cas, vous devez définir manuellement les propriétés IsDbGenerated=true et AutoSync=Always/OnInsert/OnUpdate.

Plusieurs options de chargement de données

Q. Puis-je spécifier des options de chargement supplémentaires sans remplacer la première ?

R. Oui. La première n'est pas remplacée, comme dans l'exemple suivant :

Dim dlo As New DataLoadOptions()
dlo.LoadWith(Of Order)(Function(o As Order) o.Customer)
dlo.LoadWith(Of Order)(Function(o As Order) o.OrderDetails)
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Order>(o => o.Customer);
dlo.LoadWith<Order>(o => o.OrderDetails);

Erreurs lors de l'utilisation de SQL Compact 3.5

Q. J'obtiens à une erreur lorsque je fais glisser des tables hors d'une base de données SQL Server Compact 3.5.

R. Concepteur Objet/Relationnel ne prend pas en charge SQL Server Compact 3.5, alors que c'est le cas du runtime LINQ to SQL. Dans ce cas, vous devez créer vos propres classes d'entité et ajouter les attributs appropriés.

Erreurs dans les relations d'héritage

Q. J'ai utilisé la forme de l'héritage de la boîte à outils dans Concepteur Objet/Relationnel pour connecter deux entités, mais j'obtiens des erreurs.

R. Il ne suffit pas de créer la relation. Vous devez fournir des informations telles que la colonne du discriminateur, la valeur du discriminateur de la classe de base et la valeur du discriminateur de la classe dérivée.

Modèle de fournisseur

Q. Un modèle de fournisseur public est-il disponible ?

R. Aucun modèle de fournisseur public n'est disponible. Actuellement, LINQ to SQL prend en charge uniquement SQL Server et SQL Server Compact 3.5.

Attaques par injection de code SQL

Q. Comment LINQ to SQL est-il protégé contre les attaques par injection de code SQL ?

R. L'injection de code SQL est un risque significatif pour les requêtes SQL traditionnelles formées par la concaténation de l'entrée d'utilisateur. LINQ to SQL évite cette injection en utilisant SqlParameter dans les requêtes. L'entrée d'utilisateur est transformée en valeurs de paramètre. Cette technique empêche l'utilisation de commandes malveillantes à partir de l'entrée d'utilisateur.

Modification de l'indicateur de lecture seule dans les fichiers DBML

Q. Comment faire pour éliminer les accesseurs Set de certaines propriétés lorsque je crée un modèle à partir d'un fichier DBML ?

R. Effectuez la procédure suivante pour ce scénario avancé :

  1. Dans le fichier .dbml, modifiez la propriété en changeant l'indicateur IsReadOnly en True.

  2. Ajoutez une classe partielle. Créez un constructeur avec des paramètres pour les membres en lecture seule.

  3. Vérifiez la valeur par défaut de UpdateCheck (Never) pour déterminer si elle convient pour votre application.

    Attention :

    Si vous utilisez Concepteur Objet/Relationnel dans Visual Studio, vos modifications peuvent être remplacées.

APTCA

R. System.Data.Linq est-il marqué pour être utilisé par du code d'un niveau de confiance partiel ?

R. Oui, l'assembly System.Data.Linq.dll figure parmi ces assemblys .NET Framework marqués par l'attribut AllowPartiallyTrustedCallersAttribute. Sans ce marquage, les assemblys contenus dans .NET Framework sont conçus uniquement pour être utilisés par du code d'un niveau de confiance suffisant.

Le scénario principal dans LINQ to SQL pour l'autorisation des appelants d'un niveau de confiance partiel consiste à permettre l'accès de l'assembly LINQ to SQL à partir des applications Web, où la configuration de la confiance est Moyenne.

Mappage de données à partir de plusieurs tables

Q. Les données de mon entité proviennent de plusieurs tables. Comment faire pour les mapper ?

R. Vous pouvez créer une vue dans une base de données et mapper l'entité à la vue. LINQ to SQL génère pour les vues le même SQL que pour les tables.

Remarque :

L'utilisation des vues dans ce scénario comporte des limitations. Cette technique est plus sûre lorsque les opérations exécutées sur Table<TEntity> sont prises en charge par la vue sous-jacente. Vous êtes le seul à connaître les opérations prévues. Par exemple, la plupart des applications sont en lecture seule, et un autre nombre important d'applications exécutent des opérations Create/Update/Delete uniquement à l'aide de procédures stockées sur des vues.

Pools de connexions

Q. Existe-t-il une construction pouvant aider au regroupement DataContext ?

R. N'essayez pas de réutiliser des instances de DataContext. Chaque DataContext gère l'état (y compris un cache d'identité) d'une session de modification/requête particulière. Pour obtenir des nouvelles instances basées sur l'état actuel de la base de données, utilisez un nouveau DataContext.

Vous pouvez néanmoins utiliser le pool de connexions ADO.NET sous-jacent. Pour plus d'informations, consultez Regroupement de connexions SQL Server (ADO.NET).

Le second DataContext n'est pas mis à jour

Q. J'ai utilisé une instance de DataContext pour stocker des valeurs dans la base de données. Toutefois, un second DataContext sur la même base de données ne reflète pas les valeurs mises à jour. La seconde instance DataContext paraît retourner des valeurs mises en cache.

R. Ce comportement est inhérent à la conception. LINQ to SQL continue à retourner les mêmes instances/valeurs que vous avez vues dans la première instance. Lorsque vous effectuez des mises à jour, vous utilisez l'accès concurrentiel optimiste. Les données d'origine sont utilisées pour effectuer la comparaison avec l'état actuel de la base de données afin de vérifier qu'il n'a en fait pas été modifié. S'il a été modifié, un conflit se produit et votre application doit le résoudre. L'une des options de votre application consiste à réinitialiser l'état d'origine à l'état actuel de la base de données et à retenter la mise à jour. Pour plus d'informations, consultez Procédure : gérer les conflits de changement (LINQ to SQL).

Vous pouvez également attribuer à ObjectTrackingEnabled la valeur false, ce qui désactive la mise en cache et le suivi des modifications. Vous pouvez ensuite extraire les valeurs les plus récentes chaque fois que vous exécutez une requête.

Impossible d'appeler SubmitChanges en mode lecture seule

Q. Lorsque j'essaie d'appeler SubmitChanges en mode lecture seule, j'obtiens une erreur.

R. Le mode lecture seule désactive la capacité du contexte à suivre les modifications.

Voir aussi

Tâches

Dépannage (LINQ to SQL)

Concepts

Sécurité dans LINQ to SQL

Autres ressources

Référence (LINQ to SQL)