SB2055
SB2055

Reputation: 12912

LINQ to Entities Casting Issues - Unable to cast object to Generic type

This is the error I'm receiving:

Message = "Unable to cast the type 'App.Models.Subject' to type 'App.Context.ITenantData'. LINQ to Entities only supports casting EDM primitive or enumeration types."

In an attempt to implement multi-tenancy in my application, I added a Tenants table and linked every tenant-specific model to a Tenant (including Subjects).

I got a lot of help from this post: DbSet, ModelBuilder, and EF Navigation Properties

But now I'm stuck with the above casting issue.

My TenantContext:

 public class TenantContext : DbContext {

    private readonly RealContext _realContext;
    private readonly Tenant _tenant;

    public TenantContext(Tenant tenant)
        : base("name=DefaultConnection") {
        this._tenant = tenant;
        this._realContext = new RealContext();
    }

    // _realContext.Subjects is a DbSet
    public IQueryable<Subject> Subjects { get { return FilterTenant(_realContext.Subjects); } }

    private IQueryable<T> FilterTenant<T>(IQueryable<T> values) where T : ITenantData
    {
        return values.Where(x => x.TenantId == _tenant.TenantId);
    }
 }

With ITenantData:

 public interface ITenantData {
    int TenantId { get; set; }
}

And Subject implements ITenantData with a TenantId property:

    [ForeignKey("Tenant")]
    public int TenantId { get; set; }

Now, when I query using TenantContext, I get the above error:

 using (var db = CreateContext()) {   // returns tenantContext
            var dbSubjects = db.Subjects;
            var subjects = dbSubjects.ToList(); // error occurs here

What am I doing wrong?

Also - I'm pretty new to this, so if I'm missing anything critical here, let me know and I'll post up. Thank you for any help you can provide.

Upvotes: 0

Views: 1209

Answers (2)

SB2055
SB2055

Reputation: 12912

Updating my TenantContext to include class fixed the problem, but I don't know why:

private IQueryable<T> FilterTenant<T>(IQueryable<T> values) where T : class, ITenantData
{
    return values.Where(x => x.TenantId == _tenant.TenantId);
}

If anyone wants to write up anything about the reasoning behind this, I'll gladly accept your answer.

Upvotes: 2

LINQ2Vodka
LINQ2Vodka

Reputation: 3036

Here:

values.Where(x => x.TenantId == _tenant.TenantId);  

translator doesnt have an idea how to translate _tenant.TenantId into SQL

Upvotes: -1

Related Questions