I think the solution for my question is very simple.
I need to know how I can loop through all the member so I can send an e-mail depending on a custom setting. But I can't figure out what to write to loop through them all.
Oops...Forgot to mention that I'm trying to loop through it using C# and that it's a C# answer I'm looking for. Just can figure out what to use from the Member API...
Can use Member.GetAll property (hey, is should be a method, but that's a different discussion) which returns a member array and loop through the list (be aware of performance here).
Or, write a nice query to do the database lookup in a single query. Query won't look pretty, but it'll do the job.
I've done something similar in the past (listing/filtering members on a dashboard control), I'll try to dig up that piece of code to share.
Err advice - assign the results of Member.GetAll to a local variable, don't use it directly within a for/ foreach loop. GetAll returns a non-cached array, which means that you are executing a n^2 operation, resulting in a hell of a lot of database calls.
You should do this:
var members = Member.GetAll;
foreach(var member in members) {
// do stuff
}
That way you only access the database to return all the members once.
As for using LINQ to Umbraco, no, LINQ to Umbraco is page based, since there is no cache of the Members to work against it wouldn't be useful anyway (and you wouldn't want a member cache, there's a security issue!). But since an array does implement IEnumerable<T> you can add a reference to System.Linq and then use LINQ operations against it. It wont be any faster but it'll look cooler ;).
Does Member.GetAll return a Member object which returns all the member properties as well? If not what is the best way to find all Members which have a first name of "John"??
Think the db is the best way to do this at present. Especially when properties are involved - as I think each property issues another select.
I'm using the following SQL in an XSLT extension to get all, and get all by group etc. It's relatively expensive, but is a single hit vs lots, so I'm comfortable with it.
Hope it's useful to someone.
Chris
select m.nodeId AS Member, m.Email AS Email ,p.Name as Name, ISNULL(CONVERT(VARCHAR, d.dataInt), d.dataNvarchar) as Data
from cmsMember m
inner join cmsPropertyData d on d.contentNodeId = m.nodeId
inner join cmsPropertyType p on p.id = d.propertytypeid
inner join cmsMember2MemberGroup mg on mg.Member = m.nodeId
Every time you query an object which inherits from CMSNode (member, document, media, etc) you will likely do a database access. This is actually dependent on the DataType and how it's storing the data. Since all the OOTB data types store in the database when you do getProperty("MyProperty").Value it will query the database.
There isn't a way around this, it's from the design of Umbraco itself.
If you have large numbers of members and you need to do "searching" against them I'd write my own SQL in a .NET component and then construct the Member object myself (or an object which represents the data which I required for that request).
How to loop through all members?
Hi Guys
I think the solution for my question is very simple.
I need to know how I can loop through all the member so I can send an e-mail depending on a custom setting. But I can't figure out what to write to loop through them all.
Thanks
/Jan
Oops...Forgot to mention that I'm trying to loop through it using C# and that it's a C# answer I'm looking for. Just can figure out what to use from the Member API...
umbraco.cms.businesslogic.member.Member.GetAll
(http://umbraco.codeplex.com/SourceControl/changeset/view/64743#894655)
But it's *slow* if you have more than 500 members - now you're warned ;)
Thanks Niels. Just what I was looking for.
No worries - I don't think the number of members will be higher than 50 or so.
/Jan
ie.
using umbraco.cms.businesslogic.member; // Add reference to cms.dll
foreach(Member m in Member.GetAll) {
// m.Text <= name of member
// m.Email <= Well, you know
// m.GetProperty("phoneNo").Value.ToString() <= a custom property with the alias of "phoneNo"
}
Jan,
Can use Member.GetAll property (hey, is should be a method, but that's a different discussion) which returns a member array and loop through the list (be aware of performance here).
Or, write a nice query to do the database lookup in a single query. Query won't look pretty, but it'll do the job.
I've done something similar in the past (listing/filtering members on a dashboard control), I'll try to dig up that piece of code to share.
Cheers,
/Dirk
Gotta love LINQ ;-)
Is LINQ 2 Umbraco the guy for such a job? Or is L2U focussed on other things?
Thanks for all your replies guys. I got my function working now and it's sweet! :)
@Dirk - Would be cool if you made a wiki-entry with your code sample.
@kipsoep - Maybe Linq could have been used as well...but I'm even more a n00b when it comes to Linq than C#...;-)
/Jan
Err advice - assign the results of Member.GetAll to a local variable, don't use it directly within a for/ foreach loop. GetAll returns a non-cached array, which means that you are executing a n^2 operation, resulting in a hell of a lot of database calls.
You should do this:
That way you only access the database to return all the members once.
As for using LINQ to Umbraco, no, LINQ to Umbraco is page based, since there is no cache of the Members to work against it wouldn't be useful anyway (and you wouldn't want a member cache, there's a security issue!).
But since an array does implement IEnumerable<T> you can add a reference to System.Linq and then use LINQ operations against it. It wont be any faster but it'll look cooler ;).
Hi Slace
Thanks for letting me know this. I'll change my code accordingly when I check in at the office tomorrow.
Does Member.GetAll return a Member object which returns all the member properties as well? If not what is the best way to find all Members which have a first name of "John"??
If Member.GetAll is not a way to fetch 500+ members how should I approach fetching 4000 members? It cant be best practice to access db directly right?
/Jesper Ordrup
hi,
Think the db is the best way to do this at present. Especially when properties are involved - as I think each property issues another select.
I'm using the following SQL in an XSLT extension to get all, and get all by group etc. It's relatively expensive, but is a single hit vs lots, so I'm comfortable with it.
Hope it's useful to someone.
Chris
select m.nodeId AS Member, m.Email AS Email ,p.Name as Name, ISNULL(CONVERT(VARCHAR, d.dataInt), d.dataNvarchar) as Data
from cmsMember m
inner join cmsPropertyData d on d.contentNodeId = m.nodeId
inner join cmsPropertyType p on p.id = d.propertytypeid
inner join cmsMember2MemberGroup mg on mg.Member = m.nodeId
ORDER BY nodeID, p.Name
FOR XML AUTO
Every time you query an object which inherits from CMSNode (member, document, media, etc) you will likely do a database access. This is actually dependent on the DataType and how it's storing the data. Since all the OOTB data types store in the database when you do getProperty("MyProperty").Value it will query the database.
There isn't a way around this, it's from the design of Umbraco itself.
If you have large numbers of members and you need to do "searching" against them I'd write my own SQL in a .NET component and then construct the Member object myself (or an object which represents the data which I required for that request).
is working on a reply...