2017-05-03 11 views
0

J'ai créé un datatable où une colonne est spécifiée comme type URI. C'est parce que je veux plus tard utiliser la table comme source pour la liaison à une grille dans WPF, générant automatiquement une colonne de la grille avec un lien hypertexte. Comment puis-je remplir cette base de données à partir de ma base de données SQL Server?Comment remplir une table de données avec une colonne de type URI de SQL?

Voici mon exemple de code: -

_tblMarketPlaces = new DataTable("MarketPlaces"); 
_tblMarketPlaces.Columns.Add("MarketPlaceID"); 
_tblMarketPlaces.Columns.Add("MarketPlaceIdentifier"); 
_tblMarketPlaces.Columns.Add("MarketPlaceName"); 
_tblMarketPlaces.Columns.Add("MarketPlaceHomeUri",typeof(Uri)); 
_tblMarketPlaces.Columns.Add("DisplayPriorityOrder"); 

_tblMarketPlaces.Clear(); 

_tblMarketPlaces.Rows.Add(0, "N/A", "Unknown", DBNull.Value, 0); 

SqlConnection DB = ArtContentManager.Static.Database.DBReadOnly; 
string sqlSelectMarketPlaces = "Select * from MarketPlaces Order By DisplayPriorityOrder"; 
SqlCommand cmdSelectMarketPlaces = new SqlCommand(sqlSelectMarketPlaces, DB); 

SqlDataAdapter sdaMarkePlace = new SqlDataAdapter(cmdSelectMarketPlaces); 
sdaMarkePlace.Fill(_tblMarketPlaces); 

Le problème est que la dernière déclaration de remplissage échoue parce que le type de données de MarketPlaceHomeUri est nvarchar sur la base de données et n'est pas reconnu comme un URI. Est-il possible de persuader le DataAdapter de convertir les données dans le remplissage? [Je sais qu'une autre approche serait d'utiliser le datatable simplement pour le champ, puis de formater la colonne explicitement dans mon WPAM Xaml, mais je voudrais utiliser des colonnes autogénérées là-bas et cela semble possible si seulement je peux charger le données dans le datatable]

Répondre

0

J'ai trouvé une solution à ce problème si cela aide quelqu'un d'autre. Vous pouvez gérer une erreur de remplissage sur l'adaptateur de données et faire votre propre chose pour remplacer le mécanisme de remplissage par défaut et réparer un type de données sur le chemin.

Dans mon cas, j'ajouté ceci: -

sdaMarkePlace.FillError += new FillErrorEventHandler(FillError); 

et ce qui a fait le tour ensemble ...

private static void FillError(object sender, FillErrorEventArgs args) 
    { 
     Uri rowURI; 

     if (args.Errors.GetType() == typeof(System.ArgumentException)) 
     { 
      if (Uri.IsWellFormedUriString(args.Values[3].ToString(), UriKind.Absolute)) 
      { 
       // The URI is valid. This should be ensured in the database update but don't assume it is for defensive coding reasons 
       rowURI = new Uri(args.Values[3].ToString()); 
       DataRow myRow = args.DataTable.Rows.Add(new object[] 
       {args.Values[0], args.Values[1], args.Values[2], rowURI, args.Values[4]}); 
      } 
      else 
      { 
       // The URI is invalid. Update with a Null value for that field 
       DataRow myRow = args.DataTable.Rows.Add(new object[] 
      {args.Values[0], args.Values[1], args.Values[2], DBNull.Value, args.Values[4]}); 
      } 

      args.Continue = true; 
     } 
    } 

je réalise la logique ci-dessus n'est pas parfait, car il suppose Toutes les exceptions d'argument de remplissage sont dues au problème d'URI qui n'est pas forcément toujours vrai, mais un peu plus de peaufinage devrait m'amener à une solution complète. Fonctionne bien avec les colonnes de la grille autogénérée WPF maintenant.

+0

Pas très élégant car il y a des dépendances sur l'ordre des données dans le SQL, la table de données et la logique de gestion des erreurs qui sapent le point d'autogénération des colonnes et le rendent plus désordonné que la structure de la table changements, mais il y a probablement des façons de le rendre un peu plus générique. Aussi, si vous attendez une erreur pour chaque ligne, est-ce vraiment un bon design? Mais c'est une solution possible au moins ... – DMFW

0

Pouvez-vous fournir un exemple d'URI que vous voulez mettre dans MarketPlaceHomeUri? Peut-être qu'il n'est pas conforme à l'exigence de validation de l'URI (la partie où vous appelez typeof (Uri)). Rendre l'URI aussi complète que possible (avec http://www ou quelque chose).

+0

System.ArgumentException était non gérée HResult = -2147024809 Message = Type de valeur a une incompatibilité avec magasin colonne typeCouldn't dans la colonne MarketPlaceHomeUri. Le type attendu est Uri. – DMFW

+0

Ce qui précède est mon erreur qui provient du premier enregistrement de mon fichier. Je vois que l'échange de pile a converti le texte dans le message d'erreur en un lien. Dans le texte brut d'origine, il s'agit d'une URL complète qui fonctionne lorsqu'elle est copiée dans une barre d'adresse du navigateur et contient le préfixe http: \\ complet – DMFW

+0

Si j'ajoute un enregistrement "manuellement" au datatable selon le premier exemple factice du code, cela fonctionne si la valeur est DBNull.Value ou si je lance explicitement en tant qu'objet URI, ce qui est logique. Je soupçonne que la méthode Fill ne lance pas la chaîne et je me demande si je peux le convaincre de le faire. – DMFW