Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TPH Inheritance and filtering problem #62

Open
hikalkan opened this issue Apr 10, 2016 · 8 comments
Open

TPH Inheritance and filtering problem #62

hikalkan opened this issue Apr 10, 2016 · 8 comments

Comments

@hikalkan
Copy link

I have this inheritance:

    public abstract class FeatureSetting
    {
        public int Id { get; set; }

        public virtual string Name { get; set; }

        public virtual string Value { get; set; }
    }

    public class EditionFeatureSetting : FeatureSetting
    {
        public virtual int EditionId { get; set; }
    }

    public class TenantFeatureSetting : FeatureSetting, IMustHaveTenant
    {
        public virtual int TenantId { get; set; }
    }

My filtering interface is IMustHaveTenant. I defined filter as shown below:

modelBuilder.Filter(AbpDataFilters.MustHaveTenant, (IMustHaveTenant t, int tenantId) => t.TenantId == tenantId, 0);

All is good. But, when I query EditionFeatureSettings from database, it adds TenantId filter to the query, and thus I can not get any EditionFeatureSettings. Actually, filtering should be only applied for TenantFeatureSetting, since only it defines TenantId. So, when I query EditionFeatureSettings, it should not apply any filtering, but it does.

Thanks a lot.

@jcachat
Copy link
Collaborator

jcachat commented Apr 10, 2016

So it's adding a filter against the "TenantId" column on the EditionFeatureSession table? Is that generating a SQL error then since the column TenantId does not exist in table EditionFeatureSession?

I have never seen a filter wrongly applied to an entity before...

@hikalkan
Copy link
Author

Oh, this is TPH. That means both entities are in the same table.

@hikalkan
Copy link
Author

And also I saw it in unit tests, not tested against SQL Server to see generated SQL. I can also do it if this is not enough.
Thanks a lot.

@jcachat
Copy link
Collaborator

jcachat commented Apr 10, 2016

I'll take a look at this in more detail. But at first glance, this is going to be a difficult situation to handle - if it's possible at all.

That filter would need to know to automatically include a condition that matches on a discriminator value. And the only immediate information I have to go on is "IMustHaveTenant" which obviously has no knowledge of the entity being TPH, let alone the column name of the discriminator and what value should be used.

At this point (5 minutes of research), I don't know if EF exposes enough information for me to figure this out. Especially to the level of determining the discriminator values that would be needed.

2 possible workarounds that come to mind:

  1. If you have re-mapped the discriminator column to specific values in your entities, you can change your filter to include a condition on those values (see "Change Discriminator Column here for what I am talking about: http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph).
  2. Or if you let TenantId default to 0 for your FeatureSetting entities and it's always > 0 for TenantFeatureSetting, you can change your filter to "(t.TenantId == 0) || (t.TenantId == tenantId)".

I'll see if I can come up with a better solution but it may take some time.

@hikalkan
Copy link
Author

Thank you for your comments. I'll try workarounds and write here again.

@hikalkan
Copy link
Author

Hi again,

I changed my filter definition like that:

modelBuilder.Filter(AbpDataFilters.MustHaveTenant, (IMustHaveTenant t, int tenantId) => t.TenantId == tenantId || (int?)t.TenantId == null, 0);

and it worked! It seems strange to cast int to int? but it's null for EditionFeatureSetting entities, and it works.

Thank you much for leading me to the right direction.

hikalkan added a commit to aspnetboilerplate/aspnetboilerplate that referenced this issue Apr 11, 2016
@jcachat
Copy link
Collaborator

jcachat commented Apr 11, 2016

Glad to hear you found a solution. I'll keep this issue open until I have a chance to look at it closer. Maybe I can come up with a cleaner solution.

KenProDev pushed a commit to KenProDev/aspnetboilerplate that referenced this issue Jan 17, 2017
@gogosweb
Copy link

gogosweb commented Dec 3, 2018

Changed my filter definition like that gives no warning at all:

modelBuilder.Filter(AbpDataFilters.MustHaveTenant, (IMustHaveTenant t, int tenantId) => t.TenantId == tenantId || (t.TenantId as int?) == null, 0);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants