Umbraco Get Users by User Type - umbraco

If I have a list of user types (both ID and name), how can I get the users that belong to that user type (not members)? There doesn't seem to be any methods for User[] userList = User.Get ByType

Using linq you should be able to get what you're looking for. Here's an example of how to get Users based solely on the alias of the User Type:
string[] userTypeAliases = new string[] { "writer", "editor" };
var userTypes = umbraco.BusinessLogic.UserType.GetAllUserTypes()
.Where(ut => userTypeAliases.Contains(ut.Alias));
var users = umbraco.BusinessLogic.User.getAll()
.Where(u => userTypes.Contains(u.UserType));

You can do it using IDs like this:
var userType = UserType.GetUserType(1);
var users = User.getAll().Where(u => u.UserType == userType);

Related

asp.net MVC EF 6 Identity only allowed to select 'lower' roles

I have these roles setup within identity and one role is assigned per user
00 - Super Admin
10 - Admin
20 - Staff Manager
30 - Staff
40 - User Manager
50 - User
The aim is to allow a user to change the role of other users below (not equal to) their own user role
so if I could get the first two chars from the Name of the role added to the current user e.g. 30 then the choice of roles that could be applied to other users would be > 30
to get the user state of the current user
var currentUser = await _userManager.GetUserAsync(HttpContext.User);
var currentUserRole = await _userManager.GetRolesAsync(currentUser);
Then something like below that get all the roles, with 'WHERE' clause, or following if statement, first two chars > current users first two chars
var allRoles = _roleManager.Roles.ToList();
Does anyone know of a way that this could be done, or if there is a better idea?
Many Thanks
EDIT:
Ok, I now have this hardcoded to a SelectList in the view, select roles > 30 which is working
ViewBag.allRoles = _roleManager.Roles.Where(a => Convert.ToInt32(a.Name.Remove(2)) > 30).Select(a => new SelectListItem()
{
Value = a.Id.ToString(),
Text = a.Name.Remove(0, 5).ToString(),
}).ToList();
just need to get the current user role name to a string?
I have managed to sort it
var currentUser = await _userManager.GetUserAsync(HttpContext.User);
var currentUserRole = await _userManager.GetRolesAsync(currentUser);
int currentUserRoleLevel = int.Parse(currentUserRole[0].Remove(2));
ViewBag.allRoles = _roleManager.Roles.Where(a => Convert.ToInt32(a.Name.Remove(2)) > currentUserRoleLevel).Select(a => new SelectListItem()
{
Value = a.Id.ToString(),
Text = a.Name.Remove(0, 5).ToString(),
}).ToList();
The question still stands, is there a better way?

Return table records based on user role / table Join failing - linq query

I am building a MVC 5 (EF6) application that has a photographer table that's linked to the users table.
I identify a photographer by setting a role on the user account. The photographer table holds additional information not table. I have different types of users accessing the system.
I need to get the photographer table records based on the user being in the photographer role. I have the following solution but it comes back with the following error message when i try to access query result.
Unable to create a constant value of type 'Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole'. Only primitive types or enumeration types are supported in this context.
var photogpraherRole = db.Roles.Single(r => r.Name == "photographer");
var users = photogpraherRole.Users.ToList();
var photographersList =
from photographer in db.Photographers
join user in users on photographer.User.Id equals user.UserId
orderby photographer.Priority
select photographer;
foreach (var photographer in photographersList)
{
var photographerName = photographer.User.FirstName;
}
After some research and the help from #Shawn Yan, this is the solution i came up with.
var photographerRole = db.Roles.SingleOrDefault(m => m.Name == "photographer");
var disabledRole = db.Roles.SingleOrDefault(m => m.Name == "disabled");
var users = db.Users.Where(m => m.Roles.All(r => r.RoleId == photographerRole.Id && r.RoleId != disabledRole.Id)).ToList();
var photographersList =
from photographer in db.Photographers.ToList()
join user in users on photographer.User.Id equals user.Id
where photographer.Location == booking.location.Location
orderby photographer.Priority
select photographer;
var photographers = photographersList.ToList();

How to get data from one table and then compare it with other table?

I have "Products table" with following fields
PID int,
product_name varchar(),
product_price int
"Cart table" with following fields
cart_ID
user_id
PID
So I want to display cart items of logged in user
For example if user_ID=100 is logged in , then only his cart items should be displayed to him, with all the product details.
Am using asp.net with entity framework
public ActionResult Cart()
{
Products pro = new Products();
Cart cart =new Cart();
var productID = db.cartDetails.Where(pid => pid.productId == cart.productId && cart.user_id == session["user_ID"]);
return View(db.productsDetails.Where(pid => pid.productId == productID));
}
Now problem arises, ProductID being var type I cannot compare it with pid => pid.productid.
What I want to do is first get all the product_id's of user from cart table by comparing uid_id (Logged in user) with user_id in cart table, then displaying product details of those product_id's from product Table. So obviously I need to store multiple product_id's,so that i can populate their data on the cart page.
The LINQ expression db.cartDetails.Where(pid=>pid.productId==cart.productId && cart.user_id==session["user_ID"]) would return a collection of cartDetails and not the productId. You must use select to fetch the columns you need, something like this
var productIDs = db.cartDetails
.Where(pid => pid.productId == cart.productId && cart.user_id == session["user_ID"])
.Select(cd => cd.productId)
.ToList();
This would return you a List of productIds. (If you wish to get only one productId, you could use SingleOrDefault or FirstOrDefault depending on your scenario like db.cartDetails.SingleOrDefault(pid => ...).productId).
Also note that you could have used int type for productId instead of using var if you were expecting an integer. Now you are getting a collection type IQueryable<cardDetails> being assigned to productId.
Next you cannot use an equality operator for the returned List anymore, you should check if this list contains the productId from productDetails, something like this:
return View(db.productsDetails.Where(pid => productIDs.Contains(pid.productId)));
Couldn't test this code, but the basic idea is here.
One last thing, consider using a join between the two tables: https://msdn.microsoft.com/en-us/library/bb311040.aspx
Did this and now my cart is working fine
public ActionResult Cart()
List<int> productIDs = new List<int>();
productIDs = db.cartDetails.Where(ch => ch.userId ==12).Select(cd => cd.productId).ToList() ;
List<Products> pDetails = new List<Products>();
for(int i=0;i<productIDs.Count;i++)
{
pDetails.Add(db.productsDetails.Find(productIDs[i]));
}
return View(pDetails);

load navigation properties with filter for Entity Framework 4.3

Few days back I put a question regarding mapping two classes Message and MessageStatusHistory using EF. The mapping is going fine but I am facing some problems with the navigation property StatusHistory in class Message that relates it to MessageStatusHistory objects. I am loading the messages for one user only and want to the statuses pertaining to that user only. Like I would want to show if the user has marked message as read/not-read and when. If I use default loading mechanism like following it loads all the history related to the message irrespective of the user:
IDbSet<Message> dbs = _repo.DbSet;
dbs.Include("StatusHistory").Where(x=>x.MessageIdentifier == msgIdentifier);
To filter history for one user only I tried following trick:
IDbSet<Message> dbs = _repo.DbSet;
var q = from m in dbs.Include("StatusHistory")
where m.MessageIdentifier == msgIdentifier
select new Message
{
MessageIdentifier = m.MessageIdentifier,
/*OTHER PROPERTIES*/
StatusHistory = m.StatusHistory
.Where(x => x.UserId == userId).ToList()
};
return q.ToList();//THROWING ERROR ON THIS LINE
I am getting the error:
The entity or complex type 'MyLib.Biz.Message' cannot be constructed in a LINQ
to Entities query.
I have tried by commenting StatusHistory = m.StatusHistory.Where(x => x.UserId == userId).ToList() also but it has not helped.
Please help me in getting Messages with filtered StatusHistory.
EDIT:- above is resolved with this code:
var q = from m in _repository.DBSet.Include("Histories")
where m.MessageIdentifier == id
select new {
m.Id,/*OTHER PROPERTIES*/
Histories = m.Histories.Where(x =>
x.SenderId == userId).ToList()
};
var lst = q.ToList();
return lst.Select(m => new Message{
Id = m.Id, MessageIdentifier = m.MessageIdentifier,
MessageText = m.MessageText, Replies = m.Replies,
ReplyTo = m.ReplyTo, Histories = m.Histories, SenderId =
m.SenderId, SenderName = m.SenderName, CreatedOn = m.CreatedOn
}).ToList();
But if I try to include replies to the message with:
from m in _repository.DBSet.Include("Replies").Include("Histories")
I am getting error on converting query to List with q.ToList() for Histories = m.Histories.Where(x=> x.SenderId == userId).ToList().
About your EDIT part: You cannot use ToList() in a projection, just leave it an IEnumerable<T> and convert to a List<T> when you construct the Message. You also don't need to create two list objects, you can switch from the LINQ to Entities query to LINQ to Objects (the second Select) by using AsEnumerable():
var list = (from m in _repository.DBSet
where m.MessageIdentifier == id
select new {
// ...
Histories = m.Histories.Where(x => x.SenderId == userId)
})
.AsEnumerable() // database query is executed here
.Select(m => new Message {
// ...
Histories = m.Histories.ToList(),
// ...
}).ToList();
return list;
Be aware that Include has no effect when you use a projection with select. You need to make the properties that you want to include part of the projection - as you already did with select new { Histories.....

With Linqtosql, How to get a collection of Users based on an array of UserID's

Using linqtosql, how would I get a colleciton of User objects, if I have an array of UserID's that I want to fetch?
You can use Contains to check if each UserID is in the array that you have.
int[] userIDs = ...
var users = db.Users.Where( u => userIDs.Contains( u.UserID ) );
If you want to avoid a SET operation and user chained ORs instead, you can use the PredicateBuilder to help you with that.
It goes something like this:
var userIDs = new[] { 1, 2, 3, 4, 5 };
// build multiple OR expressions
var filter = PredicateBuilder.False<User>();
foreach (var id in userIDs) {
filter = filter.Or(x => x.UserID == id);
}
// fetch data
using (var db = new TheDataContext()) {
var users = db.Users.Where(filter);
// wham! - we have users now.
}
Take a look at the blog post to understand how it works. This basically creates a long chaining ORs for each user id in the list before passing it to a WHERE clauses.
Try this:
using(var db=new MyDataContext())
{
var users=db.Users.Where(u=>userIds.Contains(u.Id));
}

Resources