Question

I am working with Entiry Framework 6 and one of my functions will be returning the output from Database.SqlQuery which would be a DbRawSqlQuery<TElement>. I would like my interface for my class to not to have any dependencies on Entity Framework so I do not want to return the DbRawSqlQuery<TElement> directly, but I also want to expose both the IEnumerable<T> and the IListSource interfaces.

I know C# does not have "duck typing" for interfaces, so I can't just do

interface IQueryResult<out T> : IEnumerable<T>, IListSource
{    
}

//Elsewhere
public IQueryResult<T> RunQuery<T>()
{
    return this.Database.SqlQuery<T>(GetQuery());
}

I think I have to use some kind of wrapper to solve this, but is there other options?

Was it helpful?

Solution

Here is a example of how to solve this issue using a wrapper class

public interface IQueryResult<out T> : IEnumerable<T>, IListSource
{    
}

internal class QueryResultWrapper<T> : IQueryResult<T>
{
    private readonly DbRawSqlQuery<T> _source;

    public QueryResultWrapper(DbRawSqlQuery<T> source)
    {
        _source = source;
    }

    public bool ContainsListCollection
    {
        get { return ((IListSource)_source).ContainsListCollection; }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)_source).GetEnumerator();
    }

    public IEnumerator<T> GetEnumerator()
    {
        return _source.GetEnumerator();
    }

    public IList GetList()
    {
        return ((IListSource)_source).GetList();
    }
}

And then modify the calling method to be

public IQueryResult<T> CallStoredProcedure<T>(string query)
{
    return new QueryResultWrapper<T>(this.Database.SqlQuery<T>(query));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top