I am working with EF6
and am using db first generated models for MSSQL
and Oracle
. In few places I am searching by multiple search criteria which results in UNION ALL
sql generated where each query is being in it's own sub-select.
One of columns in Oracle
table is CLOB
and linq to sql
after it wraps all selects with UNION ALL
at the top of all UNIONS
it calls SELECT DISTINCT
"UnionAll1"."UNIQUE_ID" AS "C1", ...
which requires to compare CLOB
s and fails on Oracle side.
ORA-00932: inconsistent datatypes: expected - got CLOB
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: Oracle.ManagedDataAccess.Client.OracleException: ORA-00932: inconsistent datatypes: expected - got CLOB
Is there a way to remove that DISTINCT
statement? How can I make this work?
UPDATE Mechanism that generates LINQ looks like this:
public static IQueryable<T> ApplySearch<T>(this IQueryable<T> queryable, SearchModel search) where T : class
{
var subQueries = new List<IQueryable<T>>();
if (search != null)
{
if (search.PolicyNumber.HasValue && typeof (IPolicyNumber).IsAssignableFrom(queryable.ElementType))
{
subQueries.Add(queryable.SearchByPolicyNumber(search));
}
if (search.UniqueId.HasValue && typeof (IUniqueId).IsAssignableFrom(queryable.ElementType))
{
subQueries.Add(queryable.SearchByUniqueId(search));
}
if (!string.IsNullOrWhiteSpace(search.PostCode) && typeof(IPostCode).IsAssignableFrom(queryable.ElementType))
{
subQueries.Add(queryable.SearchByPostCode(search));
}
}
return subQueries.DefaultIfEmpty(queryable)
.Aggregate((a, b) => a.Union(b));
}
Example of specific search method:
public static IQueryable<IRequestId> SearchByRequestId<IRequestId>(this IQueryable<IRequestId> queryable, SearchModel search)
{
var interfacesToColumnNames = new Dictionary<Type, string>
{
{typeof (IRequestId<>), "requestid"},
{typeof (IRequest_Id<>), "request_id"},
};
var paramLambda = Expression.Parameter(typeof (IRequestId));
var columnLambda = Expression.Property(paramLambda, interfacesToColumnNames.Single(o => queryable.ElementType.GetInterfaces().Any(oo => oo.Name == o.Key.Name)).Value);
var lambda = Expression.Lambda<Func<IRequestId, bool>>(
Expression.Equal(columnLambda, Expression.Convert(Expression.Constant(search.RequestId), columnLambda.Type)), paramLambda);
queryable = queryable.Where(lambda);
return queryable;
}
Example where it gets called in controller:
public ActionResult QUOTE_HOUSE()
{
var onlineDocs =
this.DatabaseManager.GetEntities<QUOTE_HOUSE>().ApplySearch(Search)
.Take(10);
return View("QUOTE_HOUSE", onlineDocs.ToList());
}