Query Surface
Summary
The Query Surface is akin to it's Linq to Sql counterpart in that it defines the objects that you can query against. Specifically: *IQueryable
tables *Aggregates (Avg, Min, Max, etc **Select, Update, Insert The Query Surface allows you to work against a specific database that is "surfaced" by SubSonic.
Implementation
The Query Surface is an implementation of SubSonic's IQuerySurface class:
namespace SubSonic.Query { public interface IQuerySurface { SqlQuery Avg(Expression> column); SqlQuery Count(Expression> column); SqlQuery Max(Expression> column); SqlQuery Min(Expression> column); SqlQuery Variance(Expression> column); SqlQuery StandardDeviation(Expression> column); SqlQuery Sum(Expression> column); SqlQuery Delete(Expression> column) where T : new(); Query GetQuery(); ITable FindTable(string tableName); ITable FindTableByClassName(string className); IDataProvider Provider { get; } Select Select { get; } Insert Insert { get; } Update Update() where T : new(); } } The Query Surface class is created using
templates, which examine your database and create the IDataProvider implementation as well as the schema definitions required to run SubSonic 3.0.
Example
The QuerySurface is fairly flexible and you can alter it as needed - as long as you implement the core interface. The naming of the tables, for example, is up to you as is the naming of the schema elements. Here is an example of a generated Query Surface for Chinook, our sample development database:
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using SubSonic.DataProviders; using SubSonic.Linq; using SubSonic; using SubSonic.Schema; using System.Data; using SubSonic.Extensions; using SubSonic.Query; using SubSonic.Linq.Structure; using System.Linq.Expressions; namespace SubSonic.Web.Models{ public partial class DB:IQuerySurface{ private DB() { } static DB db; public static DB CreateDB() { if (db
null) { _db = new DB(); _db.Init(); } return _db; } public static void CloseDB(){ _db=null; } public IDataProvider DataProvider = ProviderFactory.GetProvider("Chinook"); public DbQueryProvider provider; public ITable FindByPrimaryKey(string pkName){ return DataProvider.Tables.SingleOrDefault(x => x.PrimaryKey.Name.Equals(pkName, StringComparison.InvariantCultureIgnoreCase)); } public Query GetQuery() { return new Query(provider); } public ITable FindTable(string tableName) { return DataProvider.FindTable(tableName); } public ITable FindTableByClassName(string tableName) { return DataProvider.FindTableByClassName(tableName); } public IDataProvider Provider { get { return DataProvider; } } public DbQueryProvider QueryProvider { get { return provider; } } BatchQuery _batch=null; public void Queue(IQueryable qry){ if(_batch==null) _batch=new BatchQuery(Provider,QueryProvider); _batch.Queue(qry); } public void Queue(ISqlQuery qry){ if(_batch==null) _batch=new BatchQuery(Provider,QueryProvider); _batch.Queue(qry); } public IDataReader ExecuteBatch(){ if(_batch==null) throw new InvalidOperationException("There's nothing in the queue"); else return _batch.ExecuteReader(); } public Query Albums{ get; set; } public Query
To create a QuerySurface, just drop the T4 Code into your project and you're off and running. The templates are available in our
.
Sharing
Our
is also home to people who want to share their templates. If you have a groovy Query Surface you'd like to share, please do!