Avoiding returning all users from wrapped MembershipProvider
I have successfully setup a basic MembershipProvider and RoleProvider in a Sitefinity 4.1 site and have run into a potential issue. Looking at the source code for MembershipProviderWrapper (provided in this thread: http://goo.gl/ahccK) and watching log outputs from my MembershipProvider it appears (though I hope I'm wrong) that a fairly routine operation in Sitefinity is retrieving all of the users in the system, dumping them into a list, and then returning this list deeper into the system as an IQueryable. In my situation I have a over 100,000 users and I do not want to be pulling all of them out of the database and dumping them into a list when Sitefinity needs to do something. Is there a way to avoid this issue? Thanks!
Yes, we are aware of this issue. Unfortunately currently our implementation does not allow another way to do that - we have to return all the records and convert the to an IQueryable interface, because our internal data structures rely on that. We plan to make an optimization in the future that will fix this problem but we are not sure when this optimization will be available. We are sorry for the inconvenience.Greetings,
I'm looking at the source code and the only place it creates an IQueryable list is GetUsers, which is only used by Delete.
Does GetUsers get called elsewhere, like via the website just by the nature of it it being a membership provider? Or are you referring to something else.
Couldn't the Delete be changed to call GetUser(item.Id)?
Eric: GetUsers is indeed being called from deeper inside the Sitefinity code due to how MembershipProviders are handled. I'm not sure precisely where the call is coming from, but via logs its clear that it's getting called quite a bit.
Lubomir: Thanks for the info!
Does the regular Sitefinity membership provider do this? If I have 100k users and the wrapper hurts performance, will the default provider be zippy?
In many places in our UserManager class we have calls like this:
var user = prov.GetUsers().Where(u => u.UserName == username).FirstOrDefault();
The regular Sitefinity provider doesn't do this, of course. The thing is the manager was written having in mind that only the regulard provider will be used. We then added the ASP.NET membership provider, which is not suited very well for this scenario so we had to improvise.
We will have to revamp the module entirely in order to make any optimizations.
I have the same problem. I defined a custom MembershipDataProvider that uses REST web services to retrieve user information. So... it is not good to get all users (probablily hundred of thousands) from the web services in order to the UserManager filters them to match the username.
Is there another option to do this?
Can you provide us with a bit more information on what exactly you want to do with the users from the provider, because if you want to manage them through the backend, all the users will be required to be loaded. However, if you trying only to log them in, you will be take advantage of some of the optimizations that will be introduced with our future versions as we have made some modifications to the current implementation and the number of IQueriable lists that we use in regard to the user management.
Sorry for the delay. We already solved this issue connecting our custom MembershipDataProvider with the users database. Thus, we could use Linq to use IQueriable. I don't like this solution, but it was the only one available in that moment.
We only wanted to authenticate (log-in) and authorize (check roles) the users. We didn't want to manage users and roles from Sitefinity Backend. Additionaly, we want to show user's username, first and last name... but nothing more. If there are some new features to do that, I will appreciate your help.
Currently, the UserManager in Sitefinity is returning all users as IQueryable<User>, so you will be able to filter this query and extract only the required users.
As for the UI, where do you want to show just the user's username, first and last name? You could make a control template to show only these fields.
Furthermore, could you please specify which version of Sitefiniity are you using?
Thanks for the quick response Yavor !
We are using 6.1.4600.0 version and currently I'm moving our product to use 6.3.5000.0 version because we want to improve performance and Sitefinity's people recommended to us this new version.
Victor Velev told me this (see the post above): "if you trying only to log them in, you will be take advantage of some of the optimizations that will be introduced with our future versions as we have made some modifications to the current implementation and the number of IQueriable lists that we use in regard to the user management". Are those optimizations on version 6.3.5000?
Let's take another approach. Let's focus on the specified issue.
Please describe in details, step by step what you are trying to achieve and then what problems you have encountered.