I have this function below which is used to get those roles which are not already assigned. I have two list now.
One which has all the roles and the other one which has those roles which are already assigned to that user.
How do I return only those which are present in allRoles but not in alreadyHaveRoles?
public dynamic GiveRolesWhichAreNotAssignedToThisUser(String token, String selectedUser, String selectedOrganization)
{
User u = InstaFood.Core.User.Get(selectedUser);
var allRoles = RolesType.GetByOrganizationType(selectedOrganization).Select(i => new
{
ID = i.Id,
Name = i.Name
});
var alreadyHaveRoles = u.GetUserRoles().Select(i => new
{
ID = i.roleTypeId,
Name = ""
});
return ?? // what should be done here?
}
Can I compare them now given that both have same attributes now?
You can use Except to return the difference of two sequences, eg:
var difference=allRoles.Except(alreadyHaveRoles);
This assumes the two sequences contain items of the same type. The objects are checked for equality using their Equals implementation.
If you want to use your own equality comparison, you need to either have your objects implement IEquatable or create a custom EqualityComparer and use the Except overload that accepts a custom EqualityComparer.
In your case, you return two anonymous types that don't even have the same fields. A human would have to guess how to compare the two types, a computer will simply refuse to compile the code. If you consider two items equal if the IDs are equal, simply return the IDs, eg:
var allRoleIds = RolesType.GetByOrganizationType(selectedOrganization)
.Select(i => i.Id);
var assignedRoleIds = u.GetUserRoles().Select(i => i.roleTypeId);
var unassignedRoleIds=allRoleIds.Except(assignedRoleIds);
Retrieving the unassigned roles is trivial after that, just use:
var unassignedRoles=RolesType.GetByOrganizationType(selectedOrganization)
.Where(role=>unassingedRoleIds.Contains(role.Id);
public dynamic GiveRolesWhichAreNotAssignedToThisUser(String token, String selectedUser, String selectedOrganization)
{
User u = InstaFood.Core.User.Get(selectedUser);
var allRoles = RolesType.GetByOrganizationType(selectedOrganization).Select(i => new
{
ID = i.Id,
Name = i.Name
});
var alreadyHaveRoles = u.GetUserRoles().Select(i => new
{
ID = i.roleTypeId,
Name = ""
});
return allRoles.Where(i=>!alreadyHaveRoles.Contains(i));
}
Not tried but it should work
Related
I have a list of Contracts and im bundling them together by clientId. But i want to return only the Contract ID.
Input =>
let c1 = {client:1,id:"c1"}
let c2 = {client:2,id:"c2"}
let c3 = {client:2,id:"c3"}
let c4 = {client:1,id:"c4"}
let c5 = {client:3,id:"c5"}
let list = [c1,c2,c3,c4,c5]
Desired Output:
[[c1.id,c4.id],[c2.id,c3.id],[c5.id]]
I have the following Function, but its returning two subgroups by its key (which is the only accessible thing i see so far)
public JsonResult checkForSameClient(long[] listOfContracts)
{
IQueryable<ContratEspace> contrats = contratEspaceRepository.Get(1, listOfContracts.Count(), listOfContracts);
var contratList = contrats.ToList();
var finalArray = contrats.GroupBy(c => c.id_clientGestion).ToList();
var answer = finalArray.Select(c=>c.Key).Distinct().ToList();
return new JsonResult() { Data = answer };
}
When you use GroupBy, you get an IGroupingwhich consists of the Key of the group, and is also an IEnumerable of the members of the group. Since you just want the id_contrat from each member, you need to select that while preserving the groups.
var answer = contrats.GroupBy(c => c.id_clientGestion)
.Select(cg => cg.Select(c => c.id_contrat));
public JsonResult checkForSameClient(long[] listOfContracts)
{
I was able to Figure it out.
I used the select Method and create a new Object just with the desired properties and then i group by it.
IQueryable<ContratEspace> contrats = contratEspaceRepository.Get(1, listOfContracts.Count(), listOfContracts);
var contratList = contrats.ToList();
var answer = contrats.Select(i => new { i.id_contrat, i.id_clientGestion }).GroupBy(i=>i.id_clientGestion).ToList();
return new JsonResult() { Data = answer };
}
I am sure the answer to this is everywhere but I am struggling to find it, perhaps I am not wording it correctly?
I have a list of items as shown:
What I want to then do is something like:
var phoneNo = res("phone_number").Value;
But what is the actual syntax?
EDIT:
Here's something I've tried to no success:
Looks like you are trying to get value from your claims. You can do so as below:
var userClaims = context.HttpContext.User as ClaimsPrincipal;
Get you claim value:
if (userClaims.Claims.Where(x => x.Type == "phone_number").FirstOrDefault() != null)
{
var phoneNumberClaim = User.Claims.Where(x => x.Type == "phone_number").FirstOrDefault().Value;
}
There is a special structure in programming for such tasks. It is called Dictionary.
I think your ToClaims method should return Dictionary, so you can access values by whatever key you want. Also you can cast your list using .ToDictionary(...), where you could split string by ":" for key and value.
From the feedback given I would like to show two of the best methods I took away from this.
The method I went with:
//set up a dictionary
var claims = ctx.User.ToClaims().ToDictionary(claim => claim.Type, claim => claim.Value);
//access as follows
var phoneNo = claims["phone_number"];
var firstName = claims["given_name"];
//etc.
Another good way:
//set up IEnumerable
var claims = ctx.User.ToClaims();
//access as follows
var phoneNos = claims.FirstOrDefault(c => c.Type == "phone_number")?.Value;
var firstName = claims.FirstOrDefault(c => c.Type == "given_name")?.Value;
//etc.
I am getting lists from service. But In that particular service i need only 2 fields values alone. I write a select query, but it is not returning all lists.
var TranslResult = serviceResponse.Result.ToList();
selectedReasons = TranslResult.Select(x => new TranslationContentEntity
{
ContentId= x.ContentId,
ContentType= x.ContentType
});
But i am getting result of the following,
You can use anonymous class like this :
selectedReasons = TranslResult.Select(x => new
{
ContentId= x.ContentId,
ContentType= x.ContentType
});
Building a bunch of reports, have to do the same thing over and over with different fields
public List<ReportSummary> ListProducer()
{
return (from p in Context.stdReports
group p by new { p.txt_company, p.int_agencyId }
into g
select new ReportSummary
{
PKi = g.Key.int_agencyId,
Name = g.Key.txt_company,
Sum = g.Sum(foo => foo.lng_premium),
Count = g.Count()
}).OrderBy(q => q.Name).ToList();
}
public List<ReportSummary> ListCarrier()
{
return (from p in Context.stdReports
group p by new { p.txt_carrier, p.int_carrierId }
into g
select new ReportSummary
{
PKi = g.Key.int_carrierId,
Name = g.Key.txt_carrier,
Sum = g.Sum(foo => foo.lng_premium),
Count = g.Count()
}).OrderBy(q => q.Name).ToList();
}
My Mind is drawing a blank on how i might be able to bring these two together.
It looks like the only thing that changes are the names of the grouping parameters. Could you write a wrapper function that accepts lambdas specifying the grouping parameters? Or even a wrapper function that accepts two strings and then builds raw T-SQL, instead of using LINQ?
Or, and I don't know if this would compile, can you alias the fields in the group statement so that the grouping construct can always be referenced the same way, such as g.Key.id1 and g.Key.id2? You could then pass the grouping construct into the ReportSummary constructor and do the left-hand/right-hand assignment in one place. (You'd need to pass it as dynamic though, since its an anonymous object at the call site)
You could do something like this:
public List<ReportSummary> GetList(Func<Record, Tuple<string, int>> fieldSelector)
{
return (from p in Context.stdReports
group p by fieldSelector(p)
into g
select new ReportSummary
{
PKi = g.Key.Item2
Name = g.Key.Item1,
Sum = g.Sum(foo => foo.lng_premium),
Count = g.Count()
}).OrderBy(q => q.Name).ToList();
}
And then you could call it like this:
var summary = GetList(rec => Tuple.Create(rec.txt_company, rec.int_agencyId));
or:
var summary = GetList(rec => Tuple.Create(rec.txt_carrier, rec.int_carrierId));
Of course, you'll want to replace Record with whatever type Context.stdReports is actually returning.
I haven't checked to see if that will compile, but you get the idea.
Since all that changes between the two queries is the group key, parameterize it. Since it's a composite key (has more than one value within), you'll need to create a simple class which can hold those values (with generic names).
In this case, to parameterize it, make the key selector a parameter to your function. It would have to be an expression and the method syntax to get this to work. You could then generalize it into a function:
public class GroupKey
{
public int Id { get; set; }
public string Name { get; set; }
}
private IQueryable<ReportSummary> GetReport(
Expression<Func<stdReport, GroupKey>> groupKeySelector)
{
return Context.stdReports
.GroupBy(groupKeySelector)
.Select(g => new ReportSummary
{
PKi = g.Key.Id,
Name = g.Key.Name,
Sum = g.Sum(report => report.lng_premium),
Count = g.Count(),
})
.OrderBy(summary => summary.Name);
}
Then just make use of this function in your queries using the appropriate key selectors.
public List<ReportSummary> ListProducer()
{
return GetReport(r =>
new GroupKey
{
Id = r.int_agencyId,
Name = r.txt_company,
})
.ToList();
}
public List<ReportSummary> ListCarrier()
{
return GetReport(r =>
new GroupKey
{
Id = r.int_carrierId,
Name = r.txt_carrier,
})
.ToList();
}
I don't know what types you have mapped for your entities so I made some assumptions. Use whatever is appropriate in your case.
I have an IQueryable I selected from a database that contains a field called "NewValue". This field will either contain a 0, 1, or 2. I want to replace the value with a string based of which number it is.
i.e 0 = "Active". I know IQueryables aren't used to change values mostly just for querying but I need to use it in the next line to add to the ViewModel
var AssessmentList = assessment
.Select(p => new LogManagementViewModel
{
newValue = p.NewValue,
});
How can I change all the values in assement.NewValue to a string?
var dictionary = new Dictionary<int, string>
{
{ 0, "Active" },
{ 1, "Inactive" },
// etc
};
var AssessmentList = assessment
.Select(p => new LogManagementViewModel
{
newValue = dictionary[p.NewValue],
});
This would work for mapping between other types as well.
var values = new [] {"StrValue1", "StrValue2", "StrValue"};
var AssessmentList = assessment
.AsEnumerable()
.Select(p => new LogManagementViewModel
{
newValue = values[p.NewValue],
});
Easiest and cleanest would be with a mapping method:
string MapToString(int value)
{
//..
}
var AssessmentList = assessment
.Select(p => new LogManagementViewModel
{
NewValue = MapToString(p.NewValue),
});
One way:
Add a new computed property onto your class (assuming you have a partial class outside of any generated code). Then that computed class can do the translation however it needs to. Your view model can reference this computed value.
I would make a constructor overload in your LogManagementViewModel that does that work for you, something like this:
public LogManagementViewModel(int NewValue)
{
switch(NewValue)
{
case 0:
this.NewValue = "Active";
break;
// etc...
}
}
IMO, this places the logic in it's proper place, let the your view model translate it as it should be, it's not the responsibility of your LINQ/Database queries.