#region MIT license
//
// MIT license
//
// Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
#if MONO_STRICT
using System.Data.Linq.Sugar;
#else
using DbLinq.Data.Linq.Sugar;
#endif
#if MONO_STRICT
namespace System.Data.Linq.Implementation
#else
namespace DbLinq.Data.Linq.Implementation
#endif
{
///
/// QueryProvider is used by both DataContext and Table
/// to build queries
/// It is split is two parts (non-generic and generic) for copy reasons
///
internal abstract class QueryProvider
{
///
/// Gets or sets the expression chain.
///
/// The expression chain.
public ExpressionChain ExpressionChain { get; set; }
///
/// Gets or sets the type of the table.
///
/// The type of the table.
public Type TableType { get; set; }
///
/// Gets the query.
///
/// The expression.
///
public abstract SelectQuery GetQuery(Expression expression);
}
///
/// QueryProvider, generic version
///
///
internal class QueryProvider : QueryProvider, IQueryProvider, IQueryable, IOrderedQueryable
{
///
/// Holder current datancontext
///
protected readonly DataContext _dataContext;
///
/// Initializes a new instance of the class.
///
/// The data context.
public QueryProvider(DataContext dataContext)
{
_dataContext = dataContext;
TableType = typeof(T);
ExpressionChain = new ExpressionChain();
}
///
/// Initializes a new instance of the class.
///
/// Type of the table.
/// The data context.
/// The expression chain.
/// The expression.
public QueryProvider(Type tableType, DataContext dataContext, ExpressionChain expressionChain, Expression expression)
{
_dataContext = dataContext;
TableType = tableType;
ExpressionChain = new ExpressionChain(expressionChain, expression);
}
///
/// Creates the query.
///
///
/// The t.
/// Type of the table.
/// The data context.
/// The expression chain.
/// The expression.
///
protected S CreateQuery(Type t, Type tableType, DataContext dataContext, ExpressionChain expressionChain, Expression expression)
{
// no way to work differently
var typedQueryProviderType = typeof(QueryProvider<>).MakeGenericType(t);
var queryProvider = (S)Activator.CreateInstance(typedQueryProviderType, tableType, dataContext,
expressionChain, expression);
return queryProvider;
}
///
/// Builds the query, given a LINQ expression
///
///
///
public IQueryable CreateQuery(Expression expression)
{
var type = expression.Type;
if (!type.IsGenericType)
throw Error.BadArgument("S0066: Don't know how to handle non-generic type '{0}'", type);
var genericType = type.GetGenericTypeDefinition();
if (genericType == typeof(IQueryable<>) || genericType == typeof(IOrderedQueryable<>))
type = type.GetGenericArguments()[0];
else
Error.BadArgument("S0068: Don't know how to handle type '{0}'", type);
return CreateQuery(type, TableType, _dataContext, ExpressionChain, expression);
}
///
/// Creates the query.
///
/// The type of the element.
/// The expression.
///
public IQueryable CreateQuery(Expression expression)
{
return new QueryProvider(TableType, _dataContext, ExpressionChain, expression);
}
///
/// Gets the query.
///
/// The expression.
///
public override SelectQuery GetQuery(Expression expression)
{
var expressionChain = ExpressionChain;
if (expression != null)
expressionChain = new ExpressionChain(expressionChain, expression);
return _dataContext.QueryBuilder.GetSelectQuery(expressionChain, new QueryContext(_dataContext));
}
///
/// Runs query
///
///
///
public object Execute(Expression expression)
{
return Execute