Pregunta

Tengo esta idea de que usar SQL VIEWS para abstraer cálculos simples de bases de datos (como un recuento de una relación) es suficiente, y no necesita procedimientos (== código de procedimiento)

Un simple sql view + una where cláusula > > un procedimiento almacenado con parámetros a veces

Mientras hacía este punto, imaginé una forma de recuperar datos de tabla / vista sin escribir SQL y sin escribir la cláusula where ...

Pero, para mi sorpresa, no parece haber una forma de lograr esto en ADO.NET 2.0 o posterior.

Déjame decirte lo que probé:

  • SqlDataAdapter + SqlCommandBuilder todavía requiere que escriba " SELECT ... FROM " y la CLÁUSULA DONDE en cadenas (además, si coloca el 'dónde', no tiene mucho uso de Actualizar / Insertar / EliminarComando)

  • los DataSets escritos solo le permiten recuperar _entire DataTable_s y luego aplicarles filtros. Los filtros son cadenas, sin escapar de la ayuda ... (¡debe duplicar la comilla simple!)

  • SQL to Entities parecía prometedor pero parece que se limitan a MSSQL, generan consultas SQL infladas, generan una pila completamente nueva de DAO (además de las clases de Modelo de dominio existentes), requieren .net 3.5+ para todo esto etc. (es decir, todas estas son desventajas para mí)

Otros ORM tienen problemas similares como SQL para Entidades.

Lo que estoy buscando es un método de tipo fuerte para acceder a las tablas de la base de datos / vistas que:

  • no viene con otro conjunto de DAO (K.I.S.S)
  • me permite consultar una tabla sin escribir " SELECTs " en cadenas (de tipo fuerte)
  • me permite filtrar ( DONDE ) una tabla con parámetros con escape adecuado (y sin recuperar todos los datos de antemano)
  • luego puede emitir actualizaciones / inserciones / eliminaciones

Soy bastante nuevo en .Net pero no estúpido: ¿existe esto?

Gracias.

¿Fue útil?

Solución

Subsonic tiene un relé herramienta de consulta que puede usar para consultar directamente en la base de datos con un objeto Query que abstrae el SQL. Si lo desea, también puede usar su función de generación de código para asignar sus tablas de base de datos a POCO, o para crear un esquema fuertemente tipado (para nombres de columnas / tablas, etc.).

Otros consejos

Realmente no creo que lo que quieras hacer sea posible sin usar algún tipo de ORM, o un DSL especializado con un compilador que de alguna manera sepa sobre el esquema de tu base de datos, información de tipo / columna , etc.

Tenga en cuenta que C # es un lenguaje de propósito general, y su compilador desconoce por completo los tipos de su base de datos, es por eso que no puede vincularlos sin usar alguna capa de abstracción, que generalmente involucra consultas SQL (cadenas) ad hoc, NHibernate o archivos de mapeo similares (más cadenas) y / o DAO.

Si no desea escribir la cláusula WHERE, una forma es usar un objeto Filter y agregar las condiciones que desee. Por ejemplo:

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

Pero no desea utilizar DAO (los clientes anteriores son tales), por lo que tendría que escribir la instrucción SQL y especificar la cláusula where:

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

Supongo que ha visto LINQ y ADO.Net Data Services y estos no cumplen algunos de sus requisitos?

Native ADO.Net es un proveedor de bases de datos y, por lo tanto, proporciona una interfaz SQL directa a las fuentes de datos subyacentes. Existen varias soluciones basadas en CRUB que simulan lo que sugiere en varios grados.

Tenemos una fuerte tendencia interna de dejar la base de datos al equipo de la base de datos y usar los servicios web como una interfaz principal para nuestras bases de datos, principalmente debido a una base de código de Delphi que aún necesita soporte.

En realidad no puedo creer que olvidé agregar ADO.Net Entity Framework que es utilizado por ADO.Net Data Services entre otros. También hay un proveedor de LINQ to Entities.

Hice algo como esto con un procedimiento almacenado una vez. Básicamente, quería especificar cualquier permutación de campos para que coincida en mi cláusula WHERE, pero no quería escribir 100 sprocs con listas de parámetros ligeramente diferentes y cláusulas where.

Entonces, hice algo como esto:

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)

Esto le permitirá llamar al sproc en su código y solo pasará los parámetros que le interesan filtrar, y el resto no se tendrá en cuenta si los deja nulos.

Entonces, puedes hacer algo como

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;
}

EDITAR: En respuesta al comentario: Fácilmente podría alterar GetSimpleCustomers para que sea DeleteSimpleCustomers cambiando el

SELECT <columns> FROM SimpleCustomers

a

DELETE FROM SimpleCustomers 

y mantén la misma lógica. Lo mismo es cierto para una actualización. Además, responderé una pregunta con una pregunta: ¿Cuántas tablas tiene que realmente necesitan este nivel de filtrado personalizado? La sintaxis sería tan similar que podría explicarlo todo en un día (o menos si elaborara un script simple para escribirlo por usted).

Si está utilizando DataSets fuertemente tipados, puede crear consultas parametrizadas en el Editor de Visual Studio agregando identificadores con el prefijo @ en la consulta. Cree un archivo DataSet XSD en Visual Studio y cree una nueva tabla llamada Productos, luego agregue una nueva consulta.

Por ejemplo:

select * from Products where Category = @category;

Esto generará automáticamente métodos para conjuntos de datos llenos u obtener tablas de datos que toman el parámetro adicional. También se encargará de escapar correctamente de las cadenas (utiliza parámetros en los objetos de comando). Utilicé esto para crear algunas aplicaciones web prototipo súper simples con bastante rapidez.

Recientemente escribí una consulta 'marco' para generar cláusulas where SQL.

El componente principal es una clase BaseQueryArgs con una función ToWhereClause () que utiliza la reflexión para convertir propiedades en secciones de cadena. Esto necesita manejar el trabajo de escapar y formatear valores correctamente.

Cualquier clase que herede BaseQueryArgs simplemente necesita declarar propiedades públicas, y terminará con un objeto de consulta fuertemente tipado. Para propiedades opcionales, hace que el valor sea anulable (tipo de referencia o Nullable & Lt; & Gt;) y el generador de SQL filtra los valores nulos.

Puede usar atributos personalizados para definir características adicionales para cada propiedad:

  • nombre de columna personalizado que difiere del nombre de la propiedad
  • manejo de valores personalizados (como el uso de un valor de fecha como una ENTRE expresión de prueba)

Esto se puede usar para crear consultas con un objeto de consulta fuertemente tipado de esta manera:

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

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

GetProductsWhere () obviamente llamaría a algún método de datos que acceda a la vista con el SQL generado.

No tengo una solución para actualizaciones / eliminaciones, pero no parece tan difícil escribir un método que convierta una instancia de objeto en una declaración SQL utilizando un interruptor o atributo para determinar el nombre de la tabla.

Esto es muy & "; enrolle su propio &"; pero eso le da la libertad de personalizarlo para sus necesidades, y no incluye una gran cantidad de envoltorio ORM / DAO pesado.

Eche un vistazo a productos Mindscapes Lightspeed

Construye modelos consultables LINQ tipeados de forma sólida que dan como resultado un código SQL eficiente en una variedad de motores de bases de datos e incluye soporte para Memcached y Lucene

He usado XPO en varios proyectos y su versión más nueva tiene mejor soporte para consultas.

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

Sin embargo, la implementación, como todas ellas, no está exenta de inconvenientes.

Utilizo Resumen de datos para mis proyectos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top