Question

J'ai cette idée que l'utilisation de SQL VIEWS pour résumer des calculs de base de données simples (tels qu'un décompte sur une relation) est suffisante et que vous n'avez pas besoin de procédures (== code de procédure)

Une simple vue SQL + une clause > > une procédure stockée avec des paramètres parfois

Tout en soulignant ce point, j’ai imaginé un moyen de récupérer des données de table / vue sans écrire de code SQL et sans écrire la clause where.

Mais, à ma grande surprise, cela ne semble pas être possible dans ADO.NET 2.0 ou version ultérieure.

Laissez-moi vous dire ce que j'ai essayé:

  • SqlDataAdapter + SqlCommandBuilder nécessite toujours que vous écriviez " SELECT ... FROM " et la WHERE CLAUSE dans les chaînes (de plus, si vous mettez le "où", vous n'avez pas beaucoup recours à Update / Insert / DeleteCommand)

  • Les
  • jeux de données typés vous permettent uniquement de récupérer _entire DataTable_s et de leur appliquer des filtres. Les filtres sont des chaînes, sans aide d'échappement ... (il faut doubler la citation simple!)

  • SQL to Entities semblait prometteur, mais ils semblent: se limiter à MSSQL, générer des requêtes SQL surchargées, générer une nouvelle pile de DAO (en plus des classes de modèle de domaine existantes), requérir .net 3.5+ pour tout cela. etc. (c’est-à-dire que ce sont des inconvénients pour moi)

D'autres ORM rencontrent des problèmes similaires à ceux rencontrés entre SQL et entités.

Ce que je recherche, c'est une méthode très typée d'accès aux tables de la base de données / vues qui:

  • ne vient pas avec un autre jeu de DAO (K.I.S.S)
  • me permet d'interroger une table sans écrire " SELECTs " en chaînes (caractères forts)
  • me permet de filtrer ( WHERE ) une table contenant des paramètres correctement échappés (et sans récupérer au préalable toutes les données)
  • peut ultérieurement publier des mises à jour / insertions / suppressions

Je suis assez nouveau sur .Net mais pas stupide: est-ce que ça existe?

Merci.

Était-ce utile?

La solution

Subsonic a un poids relativement léger outil de requête que vous pouvez utiliser pour interroger directement la base de données avec un objet Query qui résume le code SQL. Si vous le souhaitez, vous pouvez également utiliser sa fonction de génération de code pour mapper vos tables de base de données sur des POCO ou pour ne créer qu'un schéma fortement typé (pour les noms de colonne / table, etc.).

Autres conseils

Je ne crois pas vraiment que ce que vous voulez faire soit réalisable sans utiliser une sorte d'ORM ou un DSL spécialisé avec un compilateur qui en quelque sorte connaît le schéma de votre base de données, les informations de type / colonne. , etc.

Tenez compte du fait que C # est un langage généraliste et que son compilateur ignore totalement vos types de base de données. C'est pourquoi vous ne pouvez pas les lier sans utiliser une couche d'abstraction, qui implique généralement des requêtes SQL ad hoc (chaînes), NHibernate ou fichiers de mappage similaires (plus de chaînes) et / ou DAO.

Si vous ne souhaitez pas écrire la clause WHERE, vous pouvez notamment utiliser un objet Filter et ajouter les conditions souhaitées. Par exemple:

        var sc = new Filter();
        sc.Add("Contacttitle", "Sales Agent");
        sc.Add("city", "london", Logical.Or);
        var customers = D2Bk.Fetch(sc, new Customers());

Mais vous ne voulez pas utiliser de DAO (les clients ci-dessus sont tels), vous devez donc écrire l'instruction SQL et spécifier la clause where:

        DataSet ds = D2Bk.Fetch("SELECT * FROM Customers WHERE Contacttitle=@PAR1 OR City=@PAR2", "Sales Agent", "london");

Je suppose que vous avez consulté LINQ et Services de données ADO.Net et ceux-ci ne répondent pas à vos exigences?

Native ADO.Net est un fournisseur de base de données. Il fournit donc une interface SQL directe aux sources de données sous-jacentes. Il existe diverses solutions basées sur CRUB qui simulent ce que vous suggérez à divers degrés.

Nous avons une forte tendance interne à laisser la base de données à l’équipe de base de données et à utiliser Webservices comme interface principale de nos bases de données, principalement en raison d’une base de code Delphi qui doit encore être prise en charge.

Je ne peux pas croire que j'ai oublié d'ajouter ADO.Net Entity Framework utilisé entre autres par ADO.Net Data Services. Il existe également un fournisseur LINQ to Entities.

J'ai déjà fait quelque chose comme ça avec une procédure stockée. En gros, je voulais spécifier toute permutation de champs à faire correspondre dans ma clause WHERE, mais je ne voulais pas écrire 100 sprocs avec des listes de paramètres légèrement différentes et des clauses where.

Alors, j'ai fait quelque chose comme ça:

CREATE PROCEDURE [GetSimpleCustomers]
(
@ID varchar(50) = null,
@Name varchar(50) = null,
@IsActive  bit = null,
@Address1 varchar(50) = null,
@Address2 varchar(50) = null,
@City varchar(50) = null,
@State varchar(50) = null,
@Zip varchar(50) = null
)
AS

SELECT ID, Name, IsActive, Address1, Address2, City, State, Zip
FROM SimpleCustomerExample
WHERE (ID = @ID OR @ID is NULL)
AND (Name = @Name OR @Name is NULL)
AND (IsActive = @IsActive or @IsActive is NULL)
AND (Address1= @Address1 or @Address1 is NULL)
AND (Address2= @Address2 or @Address2 is NULL)
AND (City= @City or @City is NULL)
AND (State= @State or @State is NULL)
AND (Zip= @Zip or @Zip is NULL)

Ceci vous permettra d'appeler le sproc dans votre code et de ne transmettre que les paramètres sur lesquels vous souhaitez filtrer, et le reste ne sera pas pris en compte si vous les laissez nuls.

Vous pouvez donc faire quelque chose comme

public List<SimpleCustomer> GetAllCustomersFromOhio()
{
    List<SimpleCustomer> list = new List<SimpleCustomer>();
    using (SqlCommand cmd = new SqlCommand(blah blah))
    {
        cmd.Parameters.AddWithValue("State", "Ohio");//or "OH" depending on your convention
        using(IDataReader oDR = cmd.ExecuteReader())
        {
             //hydrate your list of SimpleCustomers from the record set.
        }
    }
    return list;
}

EDIT: En réponse au commentaire: Vous pouvez facilement modifier suffisamment les GetSimpleCustomers pour qu’ils soient DeleteSimpleCustomers en modifiant la

SELECT <columns> FROM SimpleCustomers

à

DELETE FROM SimpleCustomers 

et gardez la même logique. La même chose est vraie pour une mise à jour. En outre, je répondrai à une question par une question: Combien de tables avez-vous réellement besoin de ce niveau de filtrage personnalisé? La syntaxe serait si semblable que vous pourriez tout maîtriser en un jour (ou moins si vous composiez un script simple pour l'écrire à votre place).

Si vous utilisez des ensembles de données fortement typés, vous pouvez créer des requêtes paramétrées dans Visual Studio Editor en ajoutant les identificateurs précédés de @ dans la requête. Créez un fichier DataSet XSD dans Visual Studio et créez une nouvelle table appelée Produits, puis ajoutez-lui une nouvelle requête.

Par exemple:

select * from Products where Category = @category;

Ceci générera automatiquement des méthodes pour des ensembles de données remplis ou pour obtenir des tables de données qui utilisent le paramètre supplémentaire. Il gérera également les propriétés échappant aux chaînes (utilise des paramètres sur les objets de commande). Je l’ai utilisé pour créer assez rapidement des prototypes d’applications Web super simples.

J'ai récemment écrit une requête 'framework' pour générer du SQL où clauses.

Le composant principal est une classe BaseQueryArgs avec une fonction ToWhereClause () qui utilise la réflexion pour convertir les propriétés en sections de chaîne. Cela doit gérer le travail d’échappement et le formatage correct des valeurs.

Toute classe héritant de BaseQueryArgs doit simplement déclarer des propriétés publiques, et vous vous retrouvez avec un objet de requête fortement typé. Pour les propriétés facultatives, vous rendez la valeur nullable (type de référence ou Nullable & Lt; & Gt;) et le générateur SQL élimine les valeurs nulles.

Vous pouvez utiliser des attributs personnalisés pour définir des fonctionnalités supplémentaires pour chaque propriété:

  • nom de colonne personnalisé différent du nom de propriété
  • traitement des valeurs personnalisées (par exemple, une valeur de date utilisée comme expression de test BETWEEN)

Ceci peut être utilisé pour créer des requêtes avec un objet de requête fortement typé comme suit:

MyCustomQueryArgs args = new MyCustomQueryArgs
{
    ProductFamilyID = 17,
    Region = Regions.Northwest,
    Active = true
};

List<Product> product = QueryProcessor.GetProductsWhere(args);

GetProductsWhere () appellera évidemment une méthode de données qui accède à la vue avec le code SQL généré.

Je n'ai pas de solution pour les mises à jour / suppressions, mais il ne semble pas si difficile d'écrire une méthode qui convertit une instance d'objet en une instruction SQL en utilisant un commutateur ou un attribut pour déterminer le nom de la table.

C’est très & "Faites votre propre &", mais cela vous donne la liberté de le personnaliser selon vos besoins, sans inclure beaucoup d’emballages lourds ORM / DAO.

Consultez les produits Mindscapes Lightspeed

.

Il crée des modèles pouvant être interrogés LINQ fortement typés, ce qui permet d'obtenir un code SQL efficace sur de nombreux moteurs de base de données et inclut la prise en charge de Memcached et de Lucene

J'ai utilisé XPO sur plusieurs projets et leur version plus récente prend mieux en charge les requêtes.

http://www.devexpress.com/Products/NET/ORM/

L’implémentation, comme toutes, n’est cependant pas sans inconvénient.

J'utilise Résumé des données pour mes projets.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top