How could this anonymous type be useful in real life situation? Why is it good to be anoynimous?
// sampleObject is an instance of a simple anonymous type.
var sampleObject =
new { FirstProperty = "A", SecondProperty = "B" };
From MSDN Anonymous Types (C# Programming Guide):
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.
...
The most common scenario is to initialize an anonymous type with
properties from another type.
For extra info, you may read Anonymous Types in Query Expressions.
Also, consider reading SO What is the purpose of anonymous types?
Consider an example from How to: Join by Using Composite Keys (C# Programming Guide):
var query = from o in db.Orders
from p in db.Products
join d in db.OrderDetails
on new { o.OrderID, p.ProductID }
equals new { d.OrderID, d.ProductID }
into details
from d in details
select new { o.OrderID, p.ProductID, d.UnitPrice };
This example shows how to perform join operations in which you want to
use more than one key to define a match. This is accomplished by using
a composite key. You create a composite key as an anonymous type or
named typed with the values that you want to compare.
And an example of using anonymous types for grouping dara to encapsulate a key that contains multiple values from Group by Multiple Columns using Anonymous Types in LINQ to SQL:
var months = from t in db.TransactionData
group t by new { month = t.Date.Month, year = t.Date.Year }
into d
select new { t.Key.month, t.Key.year };
or beter How to: Group Query Results (C# Programming Guide):
An anonymous type is used because it is not necessary to use the
complete object to display the results
Note that the properties in the anonymous type become properties on
the Key member and can be accessed by name when the query is executed.
Typically, when you use an anonymous type to initialize a variable, you declare the variable as an implicitly typed local variable by using var. The type name cannot be specified in the variable declaration because only the compiler has access to the underlying name of the anonymous type. For more information about var, see Implicitly Typed Local Variables (C# Programming Guide).
Related
I've LINQ requests that return anonymous types like:
var result = context.Table1.Select(
x => new
{
col1 = x.col1,
col2 = x.col2
}).ToList();
That works fine, until I want to hand over the result to another function.
Than I need to specify exactly, what's type the list is. I cannot use var anymore.
But if I use
List< (string col1, string col2)> result ...
I get an "Cannot implicitly convert type ..." error.
Yes, I can create a new class for each entity. But is this the only way to handle it?
If you want to use a tuple type (that's what your (string col1, string col2) is) instead of an anonymous type (that's what your new { col1=x.col1...} is), you need another syntax:
List<(string col1, string col2)> list = context.Table1
.Select( // linq to entities
x => new
{
col1 = x.col1,
col2 = x.col2
})
.ToArray() // go on with linq to objects for use of tuple types
.Select(x => (col1: x.col1, col2: x.col2))
.ToList();
ValueTuples aren't supported in Expression trees, so you might need to use a combination of anonymous types and tuple types in your query
See Tuple types,
Choosing between anonymous and tuple types
This question already has an answer here:
Why does using anonymous type work and using an explicit type not in a GroupBy?
(1 answer)
Closed 7 years ago.
We wanted to GroupBy with a known class as the grouping key. It doesn't seem to work - LINQ appears to need to group with an anonymous class.
Is it possible to use GroupBy with a known class as the grouping key?
If not, why not?
If so, how?
This question is different than Why does using anonymous type work and using an explicit type not in a GroupBy? because it asks how to use GroupBy with a known class.
Here is a fiddle that shows what works and what fails. The one that fails doesn't create a group.
public static void Works(EnumerableRowCollection<DataRow> dataRows)
{
var grouped = dataRows.GroupBy(
row => new {
Name = row["Name"]
},
(k, g) => new {
Key = k,
Group = g.CopyToDataTable()
});
}
public static void Fails(EnumerableRowCollection<DataRow> dataRows)
{
var grouped = dataRows.GroupBy(
row => new GroupingKey {
Name = row["Name"]
},
(k, g) => new {
Key = k,
Group = g.CopyToDataTable()
});
}
The difference is in the way that comparison is performed on anonymous types vs. concrete types.
According to the GroupBy documentation:
The default equality comparer Default is used to compare keys.
For anonymous types, the default equality comparer uses a property-by-property comparison, so any two anonymous types with the same members and values will be considered equivalent.
For concrete types, the default equality comparer uses reference comparison, so any two instances of the object are always considered inequivalent, regardless of their values.
To make GroupBy work with your GroupingKey class, you can either use the overload that takes an IEqualityComparer<T> to define comparisons, or override Object.Equals in GroupingKey to perform the desired comparison.
This question is chiefly about LINQ and possibly covariance.
Two of my Entities implement the IDatedItem interface. I'd like to union, then sort these, for enumerating as a single list. I must retain entity-specific properties at enumeration-time.
To clarify by example, one approach I tried was:
Context.Table1.Cast<IDatedItem>().
Union(Context.Table2.Cast<IDatedItem>()).
SortBy(i => i.Date).
ForEach(u => CustomRenderSelector(u, u is Table1));
In trying to do this various ways, I've run into various errors.
LINQ to Entities only supports casting EDM primitive or enumeration types.
Unable to process the type '.IDatedItem[]', no known mapping to the value layer
Unable to create a constant value of type 'IDatedItem'. Only primitive types
etc.
The bigger picture:
The IDatedItem interface shown here is a simplification of the actual shared properties.
In practice, the tables are filtered before the union.
The entity-specific properties will be rendered, in order, in a web page.
In a parallel feature, they will be serialized to a JSON result hierarchy.
I'd like to be able to perform LINQ aggregate operations on the results as well.
This requires more space than a comment offers. On the other hand, this is not really an answer, because there is no satisfying answer, really.
For a Union to succeed, both collections must have the same type (or have intrinsic conversions to common types, that's what covariance is about).
So a first go at getting a correct Union could be:
Context.Table1.Select(t1 => new {
A = t1.PropA,
B = t1.PropB,
Date = t1.Date
})
.Union(
Context.Table1.Select(t2 => new {
A = t2.PropC,
B = t2.PropD,
Date = t2.Date
}))
.OrderBy(x => x.Date)
.ToList();
which projects both tables to the same anonymous type. Unfortunately, because of the anonymous type, you can't do .Cast<IDatedItem>().
Therefore, the only way to get a List<IDatedItem> is to define a type that implements IDatedItem and project both tables to that type:
Context.Table1.Select(t1 => new DateItem {
A = t1.PropA,
B = t1.PropB,
Date = t1.Date
})
.Union(
Context.Table1.Select(t2 => new DateItem {
A = t2.PropC,
B = t2.PropD,
Date = t2.Date
}))
.OrderBy(item => item.Date)
.AsEnumerable()
.Cast<IDatedItem>()
Which (I think) is quite elaborate. But as long as EF doesn't support casting to interfaces in linq queries it's the way to go.
By the way, contrary to what I said in my comment, the sorting will be done in SQL. And you can use subsequent aggregate functions on the result.
Here's the working code. My solution was to ensure all data was local, to keep LINQ-to-EF from trying to do all manner of things it knows it can't that were causing many unclear errors. Then a simple type declaration on the generic Union can take hold.
That means that, aside from the annoyances of LINQ-to-EF, the main issue here is really a duplicate of LINQ Union different types - dynamically casting to an interface? .
public virtual ActionResult Index() {
return View(StatusBoard().OrderBy(s => s.Status));
}
private IEnumerable<DefensiveSituationBoardMember> StatusBoard() {
DateTime now = DateTime.UtcNow;
DateTime historicalCutoff = now.AddDays(-1);
IEnumerable<Member> activeMembers = Context.Members.Where(n => !n.Disabled).ToList();
// IncomingAttack and Reinforcements both implement IDefensiveActivity
IEnumerable<IncomingAttack> harm = Context.IncomingAttacks.Where(n => n.IsOngoingThreat || n.ArrivalOn > historicalCutoff).ToList();
IEnumerable<Reinforcements> help = Context.Reinforcements.Where(n => !n.Returned.HasValue || n.Returned > historicalCutoff).ToList();
// Here's the relevant fix
IEnumerable<IDefensiveActivity> visibleActivity = help.Union<IDefensiveActivity>(harm);
return from member in activeMembers
join harmEntry in harm on member equals harmEntry.DestinationMember into harmGroup
join activityEntry in visibleActivity on member equals activityEntry.DestinationMember into activityGroup
select new DefensiveSituationBoardMember {
Member = member,
Posture = harmGroup.Max(i => (DefensivePostures?)i.Posture),
Activity = activityGroup.OrderBy(a => a.ArrivalOn)
};
}
Is it possible to create anonymous type in LINQ extension methods in C#?
For example LINQ query.i.e.
var CAquery = from temp in CAtemp
join casect in CAdb.sectors
on temp.sector_code equals casect.sector_code
select new
{
//anonymous types
CUSIP = temp.equity_cusip,
CompName = temp.company_name,
Exchange = temp.primary_exchange
};
Is the same behavior supported for LINQ extension methods in C#?
Do you mean "when using the extension method syntax"? If so, absolutely. Your query is exactly equivalent to:
var CAquery = CAtemp.Join(CAdb.sectors,
temp => temp.sector_code,
casect => casect.sector_code,
(temp, casect) => new
{
CUSIP = temp.equity_cusip,
CompName = temp.company_name,
Exchange = temp.primary_exchange
});
The C# language specification sets out all the translations in section 7.16. Note that in this case, as your join clause was only followed by a select clause, the projection is performed within the Join call. Otherwise (e.g. if you had a where clause) the compiler would have introduced transparent identifiers to keep the two range variables (temp and casect) available, via a new anonymous type which just kept the pair of them in a single value.
Every query expression is expressible as non-query-expression code. Query expressions are effectively a form of preprocessing.
something like this maybe...
var CAquery=CATemp.Join(.....)
.Select(temp=>new
{
CUSIP = temp.equity_cusip,
CompName = temp.company_name,
Exchange = temp.primary_exchange
});
The LINQ query you have shown is an extension method. It will simply be transformed by the compiler into a call to the Join extension method. You can create an anonymous type anywhere you can create any type, which include inside any extension methods.
I've built the following LINQ query
var activeMembers = from m in context.py3_membershipSet
join c in context.ContactSet on m.py3_Member.Id equals c.ContactId
where m.statuscode.Value == 1
orderby m.py3_name
select m;
But I've since seen an example formatted as such:
var contacts =
(
from c in xrm.ContactSet
join a in xrm.AccountSet on c.ParentCustomerId.Id equals a.Id
where a.Name == "Acme Pty Ltd"
select new
{
Name = c.FullName,
DOB = c.BirthDate,
Gender = (c.FormattedValues.Contains("gendercode") ? c.FormattedValues["gendercode"] : "Ambiguous")
}
);
(I realise this is a different set of data) What does the inclusion of the 'select new' actually do in this case?
What are the benefits of it over my example in the first code block?
I realise some might find this a tedious question, but I a want to learn LINQ and need to learn it fast. But I also don't want to run something -that I don't fully understand- on a clients live CRM
LINQ returns a collection of anonymous objects, either way. select new let's you define the layout of that object and which properties/property names are included in that anonymous object.
You can also use select new ClassName { } to return a list of instances of an entity class that you define.
As previous answers have noted both methods return an anonymous type. To fully answer your question though: "What are the benefits of the second statement over the first?"
The first statement returns all of the fields of m as-is. If you have 7 "columns" then activeMembers will contain all of them and whatever data they contain.
In the second statement you're projecting the results into a custom anonymous object that has only 3 fields. Not only that but you can perform logic on the "source fields" before storing them in the anonymous object. This gives you much of the flexibility of storing them in a container class without you actually having to define that class in code.
You could also do select new SomeClass { } which would project your results into a predefined class container.
The following pseudo-code may or may not be helpful in understanding the difference:
var myQuery = from p in someContext.someTable
group p by p.someField into g
select new MyContainer {
Field1 = g.Sum(a => a.field1)
Field2 = g.Max(a => a.field2)
};
myQuery in the above is now a collection of MyContainer. If I had omitted the class MyContainer then it would be a collection of an Anonymous Type containing the fields that I specified. Obviously, the difference here is that MyContainer has to be defined elsewhere in your code whereas the anonymous class is built/defined for you at compile time. In:
var myQuery = from p in someContext.someTable
select p;
myQuery is an anonymous class containing all of the fields and their values in someTable.
You are using the Queryable.Select<TSource, TResult>(IQueryable<TSource>, Expression<Func<TSource, TResult>>) method where ContactSet is the TSource and the of anonymous object return type is the TResult. Your code could also be written as
...Select(r => new {
Name = c.FullName,
DOB = c.BirthDate,
Gender = (c.FormattedValues.Contains("gendercode") ? c.FormattedValues["gendercode"] : "Ambiguous")
})
where the select method is returning a collection of anonymous types.
Also, there is a bit more going on under the hood since it looks like you're querying the database. Your implementation of IQueryable looks at the Select method that you've written, and translates the expression you've provided into valid SQL so that it can retrieve all the necessary information for the anonymous object that you're returning. Notice that I said your implemenation of IQuerable translates the provided expression (not function) into sql. The Select extension method only accepts expressions, not functions because it can't translate functions to sql.