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
});
Related
I have a collection of data
id int
Name string
so i want to store this data in a list.
i am writing query
List<int> storedata = tabledata.Select(p => new {p.id, p.Name});
but i am getting error. so what is the right way to do this.
I suggest using var and .ToList() if you want a list of anonymous type:
var store = tabledata
.Select(p => new {id = p.id, name = p.Name}) // Anonymous type
.ToList(); // list of anonymous type's items
Let .Net infer (var) the type for you. However, taking your data into account (id and name), you may want to store the data as a dictionary, not list:
Dictionary<int, string> data = tabledata
.ToDictionary(p => p.id, p => p.Name);
...
string name123 = data[123]; // let's have a value that corresponds to id = 123
if (data.ContainsKey(789)) {
// do we have id = 789?
}
if (data.TryGetValue(456, out var name456)) { // C# 7.0 Syntax
// If we have id = 456, return corresponding value into name456
}
There are a couple compiler errors involved in this line:
List<int> storedata = tabledata.Select(p => new {p.id, p.Name});
First, the Select() method returns an IEnumerable. Trying to store the result of a Select operation into a List just won't work.
Second, the type returned by the Select operation is a problem. The body of the selection...
p => new {p.id, p.Name}
... returns an anonymous type. The storedata variable you've defined as List expects to be populated with simple integers.
Not that I'm recommending it but the following would compile, for example:
IEnumerable<object> storedata = tabledata.Select(p => new {p.id, p.Name});
You are getting an error because the return value of Select(p => new {p.id, p.Name}) is not List<int> but it is of an IEnumerable of anonymous type which is specified by the compiler and cannot be known when you write the code.
I want to generate a strongly typed list of Roles in my controller along with two other lists which will be used in my view as various filters for sending an email. I'm aware I can generate the Roles list using the following:
var viewModel = new ListViewModel
{
Roles = db.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Id.ToString(), Text = rr.Name }).ToList(),
};
However as I am also wanting to pass two other lists to my controller I would prefer to attain the list of roles by writing the query in the following way:
var viewModel = db.Roles
.Select(x => new SendGroupEmailViewModel
{
Roles = x.Select(rr => new SelectListItem { Value = rr.Id.ToString(), Text = rr.Name }).ToList(),
};
That way I can then attain my other two lists as part of the same query, as opposed to the previous method where they would have to be effectively separate queries to the db. Obviously what is above doesn't work, I am unable .Select on the role table by writing Roles = x.Select.
My question is, why am I unable to do this and what is the correct way to query the Roles table when writing it in a similar way to the above?
Just to be clear, the reason it has to be var viewModel = db.Roles is because for whatever reason I can't access the ID/Name Roles list otherwise due to how Identity is setup in MVC. I know there are other ways of attaining the list, I would just like to know how it can be done this specific way?
edit - I should add that Roles in my viewModel is as follows:
public IEnumerable<SelectListItem> Roles { get; set; }
controller
var oList = db.Roles.Select(x => new SendGroupEmailViewModel
{
Roles = x.Roles.Select(rr => new SelectListItem { Value = rr.Id.ToString(), Text = rr.Name }).ToList();
ViewData.myList = new SelectList(oList,
},
"Value", "Text", 15); // 15 = selected item or you can omit this value
View
<%=Html.DropDownList("myList") %>
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
I have a linq query that works when it I had a list of a single value now that I change to having a List that has several properties I need to change the where clause
So this works:
List<string> etchList = new List<string>();
etchList.Add("24");
var etchVect = (from vio in AddPlas
where etchList.Any(v => vio.Key.Formatted.Equals(v))
let firstOrDefault = vio.Shapes.FirstOrDefault()
where firstOrDefault != null
select new
{
EtchVectors = firstOrDefault.Formatted
}).ToList();
However I have a new hard coded list (which will represent incoming data:
List<ExcelViolations> excelViolations = new List<ExcelViolations>();
excelViolations.Add(new ExcelViolations
{
VioID = 24,
RuleType = "SPACING",
VioType = "Line-Line",
XCoordinate = 6132,
YCoordinate = 10031.46
});
So the NEW Linq query looks like this, but is obviously will not work as
AddPlas is a List and so using this other list of excelviolations, I wish to have it do where on each one of the properties in the excelviolations list
var etchVect = (from vio in AddPlas
where excelViolations.Any(vioId => vio.Key.Formatted.Equals(vioId))
let firstOrDefault = vio.Shapes.FirstOrDefault()
select new
{
EtchVectors = firstOrDefault.Formatted
}).ToList();
Now, since this is a list within a list, I would like to do something like add in each of the properties
so for example:
where excelViolations.VioID.Any(vioId => vio.Key.Formatted.Equals(vioId))
However that is not possible, but you see that I'm trying to access the property of VioID that is in the excelViolations and match it to the Key which is in vio list
Just change this line
where excelViolations.Any(vioId => vio.Key.Formatted.Equals(vioId))
to
where excelViolations.Any(excelVio => vio.Key.Formatted.Equals(excelVio.VioID))
then i thought it will works
I have this:
// Load changelog types
ChangeLogType[] Types = ChangeLogFunctions.GetAllChangelogTypes();
foreach(ChangeLogType Rec in Types){
ListItem N = new ListItem();
N.Text = Rec.Type;
N.Value = Rec.ID.ToString();
LstChangeLogType.Items.Add(N);
}
It calls a function that returns an array of ChangeLogTypes, and then adds each one into a list control. Is there a more elegant way of doing this? I feel I'm repeating code each time I do this or something similar.
Yup, LINQ to Objects is your friend:
var changeLogTypes = ChangeLogFunctions.GetAllChangelogTypes()
.Select(x => new ListItem {
Text = x.Type,
Value = x.ID.ToString() })
.ToList();
The Select part is projecting each ChangeLogType to a ListItem, and ToList() converts the resulting sequence into a List<ListItem>.
This is assuming you really wanted a new list with all these entries. If you need to add the results to an existing list, you'd do that without the ToList call, but calling AddRange on an existing list with the result of the Select call.
It's well worth learning more about LINQ in general and LINQ to Objects in particular - it can make all kinds of things like this much simpler.
var range = Types.Select(rec =>
new ListItem { Text = rec.Type, Value = rec.ID.ToString() });
LstChangeLogType.AddRange(range);
Linq?
LstChangeLogType.Items = Types.Select(x => new ListItem()
{ Text = x.Type, Value = x.ID.ToString() }).ToList();
using System.Linq;
var items = Types
.Select (rec => ListItem
{
Text = Rec.Type;
Value = Rec.ID.ToString();
}
LstChangeLogType.Items.AddRange(items);
Using some LINQ extension methods:
LstChangeLogType.AddItems.AddRange(
Types.Select(t =>
new ListItem() { Text = t.Type, Value = t.ID.ToString() }).ToArray());