Building a dynamic anonymous type Select statement using Linq - linq

//list is IEnumeable NOT IEnumerable<T>
var IEnumerable<object> = list.AsQueryable().Cast<object>().Select(x=> .........);
object actually has a POCO underlying Anonymous class e.g
AccountId,Name,SecretInfo
What I want in the select statement is
AccountId = x.GetType().GetProperty("AccountId").GetValue(x,null),
Name = x.GetType().GetProperty("Name").GetValue(x,null)
Also I want to hide the SecretInfo Column which I can pass as a hardcoded string "SecretInfo"
Basically the select list needs to be built up dynamically on the Anonymous type....
How can this be done....Any Linq punters out there who can help me?

The answer to your question relies on anonymous types. The following code is what you can use:
var result = list.AsQueryable().Cast<Info>().Select(x => new
{
AccountId = x.AccountId,
Name = x.Name
});
Between the brackets that follow the new keyword in the select statement, you are creating an anonymous type that will have two implicitly typed read-only fields (AccountId and Name). Hope this helps!
I would like to post this quote from the linked (no pun intended) article:
Anonymous types typically are used in the select clause of a query expression to return a subset of the properties from each object in the source sequence. For more information about queries, see LINQ Query Expressions (C# Programming Guide).

Related

How to obtain property name and types (by reflexion or better) of a linq result anonymous type

I need to obtain property names and types of a linq result (by reflection or better)...
I say better because I think linq should have a structure in every query with this info!!!
for example
I have a linq query like:
dim query1 = from e0 in clients select new { e0.id, e0.name }
I pass query1 as a parameter to a function, then I need to know how much properties there are in query1, the property names and the property types...
Thx, ZEE ;)
Type memberType = query1.GetType().GetGenericArguments()[0];
foreach (var a in query1)
{
foreach (PropertyInfo pi in memberType.GetProperties())
{
Console.WriteLine(pi.GetValue(a, null));
}
}
actually I will store the PropertyInfos in a List<PropertyInfo> and in the inner foreach, use the stored properties. But the above code is the simplest to understand.
First, you shouldn't be passing query results typed as a sequence of instances of an anonymous type to another method. If you're doing this, you should make a concrete class for the query results.
You can use reflection to tear out the properties from query1 as follows. query1 will implement IEnumerable<T> for some unique type T. Once you have this type, you can call
type.GetProperties()
to get an enumeration of the anonymous type member names.

linq problem with distinct function

I am trying to bind distinct records to a dropdownlist. After I added distinct function of the linq query, it said "DataBinding: 'System.String' does not contain a property with the name 'Source'. " I can guarantee that that column name is 'Source'. Is that name lost when doing distinct search?
My backend code:
public IQueryable<string> GetAllSource()
{
PromotionDataContext dc = new PromotionDataContext(_connString);
var query = (from p in dc.Promotions
select p.Source).Distinct();
return query;
}
Frontend code:
PromotionDAL dal = new PromotionDAL();
ddl_Source.DataSource = dal.GetAllSource();
ddl_Source.DataTextField = "Source";
ddl_Source.DataValueField = "Source";
ddl_Source.DataBind();
Any one has a solution? Thank you in advance.
You're already selecting Source in the LINQ query, which is how the result is an IQueryable<string>. You're then also specifying Source as the property to find in each string in the databinding. Just take out the statements changing the DataTextField and DataValueField properties in databinding.
Alterantively you could remove the projection to p.Source from your query and return an IQueryable<Promotion> - but then you would get distinct promotions rather than distinct sources.
One other quick note - using query syntax isn't really helping you in your GetAllSources query. I'd just write this as:
public IQueryable<string> GetAllSource()
{
PromotionDataContext dc = new PromotionDataContext(_connString);
return dc.Promotions
.Select(p => p.Source)
.Distinct();
}
Query expressions are great for complicated queries, but when you've just got a single select or a where clause and a trivial projection, using the dot notation is simpler IMO.
You're trying to bind strings, not Promotion objects... and strings do not have Source property/field
Your method returns a set of strings, not a set of objects with properties.
If you really want to bind to a property name, you need a set of objects with properties (eg, by writing select new { Source = Source })

Request Genres by MovieId using LINQ to Netflix OData

I am trying to create a LINQ query to return genres by movieid. The LINQ works in LINQPAD4. Can someone help me with the proper syntax? I am getting the following errors:
Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Linq.IQueryable'. An explicit conversion exists (are you missing a cast?)
and
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
Code:(note I have wrapped Title in the following line with parenthesis, but are actually brackets in my code.
public List(Genre) GetGenresByMovieId(string movieid)
{
var genres = from t in MovieCatalog.Titles
where t.Id == "BVlLx"
select t.Genres;
return genres.ToList();
}
The right query would look like
public IEnumerable<Genre> GetGenresByMovieId(string movieId)
{
return from title in ctx.Titles
from genre in title.Genres
where title.Id == "BVlLx"
select genre;
}
In the method call syntax, you need to use SelectMany, not Select, since the filter on titles returns a list of titles (which will always contain just one title, but the compiler doesn't know that) and so you want to "concatenate" all genres for each title in the results.
The return type is actually IQueryable, but if you only plan to enumerate over it, you can use IEnumerable, or call ToList() to force execution right there in the method (the way I wrote it the query would actually execute only once you try to enumerate it).
Your problem is your projection:
select new { Name = g.Name }
That is projecting the query into an anonymous type.
You need to project into the IQueryable you have declared (IQueryable<Genre>)
When working with LINQ queries, it's preferable to use implicitly-typed variables (var).
Also, not sure why you have that extra "from" in your query, you don't need that.
Something like this should work:
var genres = from t in MovieCatalog.Titles
where t.Id = "BVlLx"
select t.Genres;
return genres.ToList();
var genres should be typed to an IQueryable<Genre>.
That is assuming you want to return a collection of Genre objects.
If you just want the name, do this:
select t.Genres.Name
But that will return a collection of string objects (and var genres should be typed to an IQueryable<string>).
However, i have no idea about the NetFlix OData API, but that should get you on the right track.

How do I perform a dynamic select in Linq?

I am trying to figure out how to dynamically specify the properties for my select clause in a linq query.
Lets say I have a collection of employee objects. At run time, the end user will be specifying which properties they would like to see for those employees, so I need to be able to dynamically construct my Linq select clause.
I have used the dynamic Linq library, but I prefer not to use that, because it requires me to build a string to pass to the select method. I'd like to understand how to do this via Expressions.
This looks like something that fits more with your requirements of not using dynamic linq.
Use Reflection to get the dynamic Column Values
//columns variable has column name as comma separated String which you
can save in DB //example string columns ="Name,Id,Age";
var strColumns =columns.split(,);
foreach(var myObject in MyObjectcollection)
{
for(int index =0;index<strColumns.count();index++)
{
//Create a collection of objects
mycollection.add(myObject.GetType().GetProperty(strColumns[index]).GetValue(myObject, null));
}
}

Return Datatype of Linq Query Result

I think I'm missing something really basic.
var signatures=from person in db.People
where person.Active==true
select new{person.ID, person.Lname, person.Fname};
This linq query works, but I have no idea how to return the results as a public method of a class.
Examples always seem to show returning the whole entity (like IQueryable<People>), but in this case I only want to return a subset as SomeKindOfList<int, string, string>. Since I can't use var, what do I use?
Thanks!
You can get concrete types out of a linq query, but in your case you are constructing anonymous types by using
select new{person.ID, person.Lname, person.Fname};
If instead, you coded a class called "Person", and did this:
select new Person(peson.ID, person.Lname, person.Fname);
Your linq result (signatures) can be of type IEnumerable<Person>, and that is a type that you can return from your function.
Example:
IEnumerable<Person> signatures = from person in db.People
where person.Active==true
select new Person(person.ID, person.Lname, person.Fname);

Resources