Purpose of IQueryable<User> GetUsers() within a custom

Posted by Community Admin on 04-Aug-2018 14:03

Purpose of IQueryable GetUsers() within a custom Membership Provider?

All Replies

Posted by Community Admin on 02-Oct-2013 00:00

I am trying to create a custom Membership Provider, and was wondering if anyone can tell me what the purpose of  IQueryable<User> GetUsers()  is?

I can see that it gets called when I am on the Admin > Users page, which makes sense, but when I am logged in as a user from my custom Membership Provider, it is also getting called one or more times on every other page too (both front-end and back-end pages).

The reason that I ask is that I am working to get the users for the custom Membership Provider from an external database, but all calls to this external database will be via a Web Service.  The external database could have thousands, or hundreds of thousands, of users in it.  I do not want to have to send all user details via the Web Service every time a page is loaded.

Has anyone else come across this problem?  Is there any way to work-around it so I don't have to return all user details for every page load?

Posted by Community Admin on 02-Oct-2013 00:00

Hi Stephan,

Yeah, this is an issue with the current implementation of this provider (MembershipDataProvider).
Let me explain:

If you look at the code, the GetUsers method is by default returning an empty IQueryable, which is normal and could be implemented.

The issue arises with a large number of users. Since this IQueryable returns ALL users and then querying them with LINQ (in memory) there will be a performance hit.
So, if you view the users grid in the backend, and have like 1 million users from your custom provider, all 1 million users will be returned. This will happen on every page.

Inside the default Sitefinity provider this does not happen, since they are using their own Queryable LINQ implementation with OpenAccess, which returns the user records already filtered.

Other options would be to use OpenAccess and Sitefinity's way of implementing these features, or even maybe a custom implementation of the query.

So, regarding your case: if you only need this Membership Provider to authenticate and authorize users, you maybe should not implement these methods that come with the MembershipDataProvider, since it causes these issues.
If you do need to list and edit users from your custom database, you should create this custom implementation for your Queries.

If you have any questions, let me know.

Kind regards,
Daniel

Posted by Community Admin on 02-Oct-2013 00:00

Daniel, thank you for your prompt replay.  Your explanation is exactly what I feared.  I will look into creating a custom implementation of the query as you suggested.  Do you have any links or sample code that might point me in the right direction?

Posted by Community Admin on 02-Oct-2013 00:00

Hi Stephan,

No problem.
I did not created such solution myself. For what I can see Sitefinity has something like this:

They have their own implementation called DynamicQueryable which implements their own queryable methods like OrderBy, Skip, Take etc.

So if we take the users Service for example, it get's all the Users via the UsersManager (using the OpenAccess provider) by calling e.g. manager.GetUsers().

It then takes the returned IQueryable collection and runs a method of DataProviderBase.SetExpressions, which takes the basic arguments of Filter, Order, Skip, Take) and calls the queryable extension methods.

Those extention methods are of the DynamicQueryable class. Each extension method calls a method CreateQuery, of another class: OpenAccessQueryProvider which is responsible for applying the query operation.

In the way it's implemented, the query is not resolved until all queries are applied, and when the collection is accessed (e.g. with ToList()).

So, it's pretty complex...
You might ask for some help through support regarding a solution for this?

Kind regards,
Daniel

Posted by Community Admin on 02-Oct-2013 00:00

Daniel, thank you again.  I will have to sit down and absorb your last post to fully understand it.  I am still learning at the moment (both ASP.NET and Sitefinity), so you assistance is helping to point me in the right direction and is greatly appreciated.

This thread is closed