Trying to execute a codeblock that uses First or FirstOrDefault methods of the IQueryable interface throws an exception. This occours after the table is casted.
Example code:
Code: Select all
ITable table2 = ctx.GetTable(typeof(Employee));
IQueryable empTable2 = table2.Cast();
IEmployee employee2 = empTable2.FirstOrDefault();
This bug was discovered after you had fixed issues reported by me in this post: http://devart.com/forums/viewtopic.php?t=13248Object of type 'System.Func`2[System.Data.IDataRecord,DevArtLinqToOracleExceptions.Employee]' cannot be converted to type 'System.Func`2[System.Data.IDataRecord,DevArtLinqToOracleExceptions.IEmployee]'.
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Devart.Data.Linq.Provider.c.a(Type A_0, SqlNode A_1, d A_2, m A_3)
at Devart.Data.Linq.Provider.DataProvider.a(Expression A_0)
at Devart.Data.Linq.Provider.DataProvider.h(Expression A_0)
at Devart.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at DevArtLinqToOracleExceptions.Program.Main(String[] args) in g:\tmp\DevartTest2\ConsoleApplication1\Program.cs:line 62
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Console app code to reproduce the exception:
Code: Select all
using System;
using System.Data.Linq.Mapping;
using System.Linq;
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,
// Scenario 1 (using FirstOrDefault without interface): Works
var firstEmployee = (from emp in ctx.GetTable()
select emp).FirstOrDefault();
Console.WriteLine(firstEmployee.Id);
// Scenario 2 (using cast with interface, but without FirstOrDefault): Works.
ITable table1 = ctx.GetTable(typeof(Employee));
IQueryable empTable1 = table1.Cast();
var qry = from e in empTable1
select e;
foreach (IEmployee employee in qry) // Throws exception here
{
Console.WriteLine(employee.Id);
break;
}
// Scenario 3 (using cast with interface and using method FirstOrDefault): Throws exception
// Object of type 'System.Func`2[System.Data.IDataRecord,DevArtLinqToOracleExceptions.Employee]'
// cannot be converted to type 'System.Func`2[System.Data.IDataRecord,DevArtLinqToOracleExceptions.IEmployee]'.
ITable table2 = ctx.GetTable(typeof(Employee));
IQueryable empTable2 = table2.Cast();
IEmployee employee2 = empTable2.FirstOrDefault();
}
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; }
}
}