After trying to cast ITable to an IQueryable, various exceptions are thrown.
I have created a complete console app that reproduces the two different exceptions I get when trying two different approaches.
Code: Select all
using System;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Devart.Data.Linq;
namespace DevArtLinqToOracleExceptions
{
/*
1. Create a console application
2. Make sure project references DevArt.Data.Linq, DevArt.Data.Oracle, etc...
3. Change connectionstring below
4. Run Oracle create script for test table:
CREATE TABLE EMPLOYEE ("ID" NUMBER NOT NULL ENABLE, "NAME" NVARCHAR2(50));
INSERT INTO EMPLOYEE (ID, NAME) VALUES (1, 'John Johnson');
INSERT INTO EMPLOYEE (ID, NAME) VALUES (2, 'Jane Doe');
COMMIT;
*/
class Program
{
static void Main(string[] args)
{
using (EntityContext ctx = new EntityContext())
{
// All the scenarios below works with Linq to Sql,
// but only scenario 1 works with Linq to Oracle
// Scenario 1: Works
var firstEmployee = (from emp in ctx.GetTable()
select emp).First();
Console.WriteLine(firstEmployee.Id);
// Scenario 2: Does not work, throws NotSupportedException
ITable table1 = ctx.GetTable(typeof(Employee));
IQueryable empTable1 = table1.WorkaroundCast();
var qry = from e in empTable1
select e;
foreach (IEmployee employee in qry) // Throws NotSupportedException here
{
Console.WriteLine(employee.Id);
break;
}
// Scenario 3: Does not work, throw NullReferenceException
ITable table = ctx.GetTable(typeof (Employee));
IQueryable empTable = table.WorkaroundCast();
foreach (Employee employee in empTable) // throws NullReferenceException here
{
Console.WriteLine(employee.Id);
break;
}
}
Console.ReadLine();
}
}
[Provider(typeof(Devart.Data.Oracle.Linq.Provider.OracleDataProvider))]
public class EntityContext : Devart.Data.Linq.DataContext
{
public EntityContext()
: base("User Id=xx;Password=xx;Server=xx;Direct=True;Sid=xx") { }
}
public interface IEmployee
{
int Id { get; set; }
string Name { get; set; }
}
[Table(Name = "EMPLOYEE")]
public class Employee : IEmployee
{
[Column(Name = "ID", IsPrimaryKey = true)]
public int Id { get; set; }
[Column(Name = "NAME")]
public string Name { get; set; }
}
public static class WorkaroundClass
{
// Workaround for NotImplemented exception as I have posted here:
// http://devart.com/forums/viewtopic.php?t=13237
public static IQueryable WorkaroundCast(this IQueryable source)
{
MethodInfo method = ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TResult) });
Expression[] expressions = new Expression[] { source.Expression };
MethodCallExpression callExpression = Expression.Call(null, method, expressions);
// CreateQuery(Expression) call is the one that is not implemented, so we use CreateQuery(Expression) instead
IQueryable query = source.Provider.CreateQuery(callExpression);
return query;
}
}
}
http://devart.com/forums/viewtopic.php?t=13237
In addition to these issues beeing fixed, we really need to know if you intend to implement all features that are available to Linq to Sql in Linq to Oracle?
Freddy Hansen