Testable DataContext with Interfaces for Databasefunctions .NET Framework

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for Oracle
Post Reply
SandDo
Posts: 1
Joined: Thu 12 Mar 2020 10:02

Testable DataContext with Interfaces for Databasefunctions .NET Framework

Post by SandDo » Thu 12 Mar 2020 10:25

Dear Support,

we created an IDatabaseContext interface for our Entity Developer Created Model for a Oracle 10g Database.
In order to abstract the implementation from our Businesslogic we created for this puporse a generic Query implementation that looks like this:

Code: Select all

public interface IDatabaseContext
{
        //Generic Table Access Interface
        Devart.Data.Linq.ITable<T> Get<T>() where T : class;
}

Implementation for the Designer:

Code: Select all

public partial class MyDataContext : Devart.Data.Linq.DataContext
{
	[....]
}

Implementation of the Interface:

Code: Select all

public partial class MyDataContext : IDatabaseContext
{
	public Devart.Data.Linq.ITable<T> Get<T>() where T : class
        {
            var result =  this.GetTable<T>();
            return result;
        }
}

So far this works to query data.

But if I want to add a Database function e.g. GetAddress in a Linq query i have to cast the interface to the concete Type implementation instead of using the interface:

Code: Select all

public List<EmployeeViewModel> GetEmployee(MyDataContext dataContext){
var query dataContext.Get<Employee>()
			.Where(x => x.id = 4711)
			.Select( x=> new EmployeeViewModel
			{
				id = x.id,
				address = dataContext.GetAddress(x.id)
			}).ToList();
return query;
}
It works if dataContext is type : MyDataContext

It does not work if dataContext is type : IDatabaseContext
Excetion: [...'Methodname' ...] is not supported for execution as SQL.

Stacktrace:
bei Devart.Data.Linq.Engine.SqlFormatter.Visitor.Visit(SqlNode node)
bei Devart.Data.Linq.Engine.SqlFormatter.Visitor.a(c3 A_0)
bei Devart.Data.Linq.Engine.SqlFormatter.Visitor.a(SqlSelect A_0)
bei Devart.Data.Linq.Engine.SqlVisitor.c(h A_0)
bei Devart.Data.Linq.Engine.SqlVisitor.Visit(SqlNode node)
bei Devart.Data.Linq.Engine.SqlFormatter.Visitor.Visit(SqlNode node)
bei Devart.Data.Linq.Engine.SqlFormatter.Visitor.a(SqlSelect A_0)
bei Devart.Data.Linq.Engine.SqlVisitor.c(h A_0)
bei Devart.Data.Linq.Engine.SqlVisitor.Visit(SqlNode node)
bei Devart.Data.Linq.Engine.SqlFormatter.Visitor.Visit(SqlNode node)
bei Devart.Data.Linq.Engine.SqlVisitor.b(a5 A_0)
bei Devart.Data.Linq.Engine.SqlFormatter.Visitor.a(a5 A_0)
bei Devart.Data.Linq.Engine.SqlVisitor.Visit(SqlNode node)
bei Devart.Data.Linq.Engine.SqlFormatter.Visitor.Visit(SqlNode node)
bei Devart.Data.Linq.Engine.SqlFormatter.a(SqlNode A_0, CommandType& A_1)
bei Devart.Data.Linq.Engine.cy.d(Expression A_0)
bei Devart.Data.Linq.Engine.cy.f(Expression A_0)
bei Devart.Data.Linq.DataProvider.a(Expression A_0)
bei Devart.Data.Linq.Engine.DataQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
bei System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
bei System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

if i do a cast on solid implementation it works too:

Code: Select all

public List<EmployeeViewModel> GetEmployee(IDatabaseContext dataContext){
var query dataContext.Get<Employee>()
			.Where(x => x.id = 4711)
			.Select( x=> new EmployeeViewModel
			{
				id = x.id,
				address = ((MyDataContext)dataContext).GetAddress(x.id)
			}).ToList();
return query;
}
I want only to use the abstract interface.
Can you give a little insight what I can do here to solve my problem ?

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Testable DataContext with Interfaces for Databasefunctions .NET Framework

Post by Shalex » Mon 23 Mar 2020 09:46

SandDo wrote: Thu 12 Mar 2020 10:25Excetion: [...'Methodname' ...] is not supported for execution as SQL.
We cannot reproduce the error. Could you please upload a small test project with the corresponding DDL script to some file exchange server (e.g.: www.dropbox.com)?

The recommended way is to use repositories instead of interfaces for a context class. Then, extend the repository by implementing interfaces. Entity Developer includes the predefined template Repository And Unit of Work. Please use it.

Post Reply