Do you know how fix this error? It` s show error in this line "foreach (int s in itemColl)"
What I have to do?
Error 1 Cannot convert type 'AnonymousType#1' to
'int' C:\Users\Rafal\Desktop\MVC ksiązka\moj
projekt\sklep\SportsStore.WebUI\Controllers\ProductController.cs 37 21 SportsStore.WebUI
var itemColl = from p in re.Kategorie
where p.Nazwa == category
select new
{
p.Id_kat
};
foreach (int s in itemColl)
{
Console.WriteLine(s);
}
You are selecting itemColl with new keyword, defining an anonymous type, you can't apply foreach loop with int type. Your current query is returning something like IEnumerable<AnonymousType>
Instead you may do:
var itemColl = from p in re.Kategorie
where p.Nazwa == category
select p.Id_Kat;
This will return IEnumerable<int> and that you can use in your current foreach loop.
But if you want to use your current query with selection on anonymous type, you have to modify your foreach loop with implicit type var, and since your current query is returning an anonymous type object you may select the Id_kat from the object. Something like.
foreach (var s in itemColl)
{
Console.WriteLine(s.Id_kat);
}
IMO, the second approach is not recommended because you are just returning an int type wrapped inside an anonymous type. Its better if you can change your query to return IEnumerable<int>
You just need to change the select to:
var itemColl = from p in re.Kategorie
where p.Nazwa == category
select p.Id_kat;
This will create an IEnumerable<int> which is what you are trying to use in the foreach.
The select new { p.Id_Kat } is creating a new Anonymous Type which is in the simplest way of saying it is a new class like this:
class AnonymousType#1
{
public int Id_Kat {get; set;}
}
var itemColl = from p in re.Kategorie
where p.Nazwa == category
//This is Anonymous Type
select new
{
//Anonymous type's attribute(s) go(es) here
IntItem = p.Id_kat
};
foreach (var s in itemColl)
{
Console.WriteLine(s.IntItem);
}
Well, you could return a real (int)-value instead of an anonymous linq-result
var itemColl = from p in re.Kategorie
where p.Nazwa == category
select p.Id_Kat;
Related
I have a project that I should place some code in other layer and because of this I should transfer a linq query to method.
This code:
var HRPersonnelContactInfoTelService = App.Api.HRPersonnelContactInfoTelService.Instance().Data();
var SMSGroupMemberService = App.Api.SMSGroupMemberService.Instance().Data();
return (from x in SMSGroupMemberService
where Recivers.Contains(x.GroupID)
join v in HRPersonnelContactInfoTelService on x.Pers_Code equals v.Pers_Code
select new { Pers_Code = (int)x.Pers_Code, Tel = v.Tel }).ToList();
I converted up code to:
public dynamic HRPersonnelContactInfoTelMethod(List<int> Recivers)
{
var HRPersonnelContactInfoTelService = App.Api.HRPersonnelContactInfoTelService.Instance().Data();
var SMSGroupMemberService = App.Api.SMSGroupMemberService.Instance().Data();
return (from x in SMSGroupMemberService
where Recivers.Contains(x.GroupID)
join v in HRPersonnelContactInfoTelService on x.Pers_Code equals v.Pers_Code
select new { Pers_Code = (int)x.Pers_Code, Tel = v.Tel }).ToList();
}
but when I use it in foreach
An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code
Additional information: 'object' does not contain a definition for 'Pers_Code'
Use it like this:
var q = App.Api.HRPersonnelContactInfoTelService.Instance().HRPersonnelContactInfoTelMethod(Recivers);
foreach (var item in Recivers)
{
var res = App.Api.SMSMessageGroupService.Instance().AddOrUpdate(null, MessageId, item);
}
foreach (var z in q)
{
string SendNumber = Number[1].Trim().Substring(0, 3) == "+98" ? Number[1].Trim() : "+98" + Number[1].Trim();
var res = App.Api.SMSMessageLogService.Instance().AddOrUpdate(null, MessageId, (int)z.Pers_Code, z.Tel.ToString(),
0, int.Parse(ddlSMSWorkingGroups.SelectedValue.ToString()), (int)z.Pers_Code, SendNumber, 0);
send.SendSMS("nazmaran", "qwerty", SendNumber, "09122596898", txtPredefinedRemarks.Text);
}
I would never use dynamic to return the result of a linq query that uses anonymous types to project the results. Instead, I would create a class that holds the results:
public class SomeName
{
public int Pers_Code { set; get; }
public string /* Change to Correct Type */ Tel { set; get;}
}
Usage:
public List<SomeName> HRPersonnelContactInfoTelMethod(List<int> Recivers)
{
var HRPersonnelContactInfoTelService = App.Api.HRPersonnelContactInfoTelService.Instance().Data();
var SMSGroupMemberService = App.Api.SMSGroupMemberService.Instance().Data();
return (from x in SMSGroupMemberService
where Recivers.Contains(x.GroupID)
join v in HRPersonnelContactInfoTelService on x.Pers_Code equals v.Pers_Code
select new SomeName() { Pers_Code = (int)x.Pers_Code, Tel = v.Tel }).ToList();
}
Creating a type to hold the results is nothing compared to the complexity of used dynamic.
It seems, that .NET can not perform dynamic typization with var and iterator through dynamic, that presents a list of object.
So, when you are creating variable with var - .NET can not predict a return type and creates a new object variable, as every type is inherited from object.
However, implementing a return type as dynamic is a bad practice - possible errors can not be found until you does not call this method. So, implement a usage of another class, as #user3185569 suggested.
All I need to get all the team members ids so that I can query the contact table.
var teamMembersIds = (from q in _repository.GetQuery<TeamMember>
(t => teamIds.Contains(t.TeamId))
select new { q.ResourceContactId }
)
.ToList();
The problem is that I need to merge it with another anonymous list of ids.
resContactIds.AddRange(teamMembersIds);
I'm getting the following error:
I tried also this:
var resContactIds = new List<int>();
foreach (var _id in teamMembersIds)
{
if(resContactIds.Contains(_id))
{
resContactIds.Add(_id);
}
}
I'm getting the following error: cannot convert from 'AnonymousType#1' to 'int'
With select new { q.ResourceContactId } you are selecting an anonymous type, if you want an List<int> then remove new and curly braces like::
var teamMembersIds = (from q in _repository.GetQuery<TeamMember>
(t => teamIds.Contains(t.TeamId))
select q.ResourceContactId //here
)
.ToList();
The problem is that I need to merge it with another anonymous list of
ids
Your other list resContactIds is also List<int>, it is not a list of anonymous objects.
One more thing to add, you can omit the call ToList in your first query since AddRange can accept IEnumerable<T>
My select statement does not return the entire Customer object, just the utrustningNr and beskrivning. How do i return it in a correct way without getting this error:
Cannot implicitly convert type 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Collections.Generic.List<fjallvick.utrustning>
public List<utrustning> searchEquipment(string equipmentNr)
{
var queryEquipment = from utrustning in globalDBConnString.context.utrustnings
where utrustning.utrustningNr == equipmentNr
select (new { utrustning.utrustningNr, utrustning.beskrivning });
return queryEquipment.ToList();
}
The problem is that your select clause is creating a new anonymous type for each item, instead of a new utrustning. You may well want something like:
var queryEquipment = from utrustning in globalDBConnString.context.utrustnings
where utrustning.utrustningNr == equipmentNr
select new utrustning {
utrustningNr = utrustning.utrustningNr,
beskrivning = utrustning.beskrivning
};
Alternatively, if globalDBConnString.context.utrustnings actually returns a sequence of ustrustning values already, you could just use:
return globalDBConnString.context.utrustnings
.Where(u => u.utrustningNr == equipmentNr)
.ToList();
If you want to only return two properties, you may well be best off creating a new type which only has those two properties - then change the return type of the method, and change the select clause to use that.
Side-note: your code would be easier to understand if you followed normal .NET naming conventions.
You are selecting a new anonymous type when you do this: select (new { utrustning.utrustningNr, utrustning.beskrivning })
You can select a specific type by doing something like this:
public List<utrustning> searchEquipment(string equipmentNr)
{
var queryEquipment = from utrustning in globalDBConnString.context.utrustnings
where utrustning.utrustningNr == equipmentNr
select new utrustning
{
utrustningNr = utrustning.utrustningNr,
utrustning.beskrivning);
};
return queryEquipment.ToList();
}
List<utrustning> queryEquipment = from Utrustning in globalDBConnString.context.utrustnings
where Utrustning.utrustningNr == equipmentNr
select new utrustning { Utrustning.utrustningNr, Utrustning.beskrivning };
return queryEquipment.ToList();
You will not be able to do this with the query you have written there... you are returning an anonymous object, which you will not be able to give a name to in your code.
Assuming that utrustningNr and `beskrivning' are both strings:
Change
select new { utrustning.utrustningNr, utrustning.beskrivning }
to:
select new Tuple<string, string>(utrustning.utrustningNr, utrustning.beskrivning);
Then your return type is
List<Tuple<string, string>>
This question already has answers here:
How to pass anonymous types as parameters?
(11 answers)
Closed 9 years ago.
var emp = (from a in AdventureWorks.PersonPhones
join b in AdventureWorks.People
on a.BusinessEntityID equals b.BusinessEntityID
join c in AdventureWorks.PhoneNumberTypes
on a.PhoneNumberTypeID equals c.PhoneNumberTypeID
select new { a, b, c }).OrderBy(n => n.c.Name);
I have this linq query which selects values in a anonymous type class.
I just want to pass this query to somemethod() and call toList() on this query stored in "emp" in that method.
Thanks!
It's possible to do this in a way that doesn't care if it's a anonymous type or not - and if you pass a method for picking out the relevant property you can even do some work on it.
private static void Process<T>(IEnumerable<T> data, Func<T, string> selector) {
foreach (var item in data) {
Console.WriteLine(selector(item));
}
}
var items = from i in db.table
select new { property = i.originalProperty, ignored = i.ignored };
Process(items, (item => item.property));
An alternative to this would be to just select the property you want into a new list
var items = from i in db.table
select new { prop1 = i.prop1, prop2 = i.prop2 };
// ... cut ... do something that requires everything in items ...
IEnumerable<string> justFirstProperties = items.Select(i => i.prop1);
Process(justFirstProperties);
You can't pass anonymous types around in a strongly typed way (only as object). You would have to create a type to represent the anonymous type structure, use reflection on the object type, or do the ToList() etc. work in this method.
You could pass it as IQueryable<dynamic>
public void SomeQueryMethod(IQueryable<dynamic> query)
{
var result = query.First();
var a = result.a; //dynamic resolution
}
....
SomeQueryMethod(emp); //this should work
But in the method all property access on the result objects will be "dynamic", without compile time checks.
Ok, I have managed to get the following working
public IQueryable getTicketInformation(int ticketID)
{
var ticketDetails = from tickets in _context.tickets
join file in _context.file_objects on tickets.ticket_id equals file.source_id
where tickets.ticket_id == ticketID
select new { tickets.ticket_id, tickets.title, tickets.care_of_email, file.filename };
return ticketDetails.AsQueryable();
}
I went ahead and created my own class (myObject) containing the primitives
ticket_id, title, care_of_email and filename. Which are the items I am returning in my linq statement.
I modified my statement to be
public IQueryable<myObject> getTicketInformation(int ticketID)
{
var ticketDetails = from tickets in _context.tickets
join file in _context.file_objects on tickets.ticket_id equals file.source_id
where tickets.ticket_id == ticketID
select new { tickets.ticket_id, tickets.title, tickets.care_of_email, file.filename };
return ticketDetails.AsQueryable()<myObject>;
}
thinking that this would make it type safe with generics, but I get the error
"Cannot convert method group 'AsQueryable' to non-delegate type 'System.Linq.IQueryable'. Did you intend to invoke the method?"
Is what I am trying to do even possible?
Does the myObject class need to implement IEnumerable or IQueryable?
Or is it best to construct the object MyObject from the linq resultset and then just return from the function the object MyObject
public myObject getTicketInformation(int ticketID)
{
....linq statement....
myObject o = null;
foreach (obj in linqstatemt)
{
o = new myObject();
o.ticket_id = obj.ticket_id
.......
}
return o;
}
You mean:
select new MyObject { TicketId = tickets.ticket_id,
Title = tickets.title, ...};
(note I tweaked the names slightly to be more C#-idiomatic)
This is an "object initializer" that creates a new MyObject (per record) and assigns the properties from the source data. What you had was an "anonymous type" initializer, which isn't the same. Note that if you have a non-default constructor, you could also use something like:
select new MyObject(tickets.ticket_id, tickets.title);
which uses the specified constructor, passing in the supplied values from the source data.
This will then be IQueryable<MyObject>; you don't need to call .AsQueryable(). Note it would be better for your function to return the typed form (IQueryable<MyObject>) than the untyped IQueryable.
This line is syntactically incorrect:
return ticketDetails.AsQueryable()<myObject>;
and should read
return ticketDetails.AsQueryable<myObject>();
Also, you're creating anonymous objects with the select new {, but you want to create myObject instances. A correct implementation would look like this:
public IQueryable<myObject> getTicketInformation(int ticketID)
{
return from tickets in _context.tickets
join file in _context.file_objects on tickets.ticket_id equals file.source_id
where tickets.ticket_id == ticketID
select new myObject() {
ticket_id = tickets.ticket_id,
title = tickets.title,
care_of_email = tickets.care_of_email,
filename = file.filename
};
}
The new SomeClass() { Property = value, ... syntax creates a SomeClass instance and sets the properties to the given values. Alternatively you could implement a constructor on the myObject class and call it in the linq statement with select new myObject(...).
As Marc stated you're not constructing instances of myObject when your query is run. But additionally you don't need to cast it to an IQueryable<T>, a LINQ select statment will return an IQueryable<T> unless explicity cast to an IEnumerable<T>.
Also, be careful that your DataContext hasn't been disposed of before you try and access the data being returned. But I noticed your context is not constructed in the method, be careful that you're not maintaining a DataContext for too long, it's a unit-of-work object and not meant to be kept open for long periods of time.
Gents,
It all makes sense as long as you're only returning single table, but what if there's two or more to be returned???
RPDTDataContext smdt = new RPDTDataContext();
var projectedUsers = smdt.SM_Users.Join(
smdt.SM_CTSGroups, u => u.CtsGroupID, c => c.id,
(u, c) => new { CTSGroup = c.Name, UserName = u.Name, u.EmpID, u.Email });
return projectedUsers;