You can use OfType<T>() in a persistence-storage LINQ query when you need MDriven to return only instances of a specific derived class; this is for developers querying model objects through LINQ.
Filter a result to a derived type
Use OfType<SomeSubClass>() after a query that selects objects typed as their base class. MDriven translates this type filter as part of the persistence-storage query, so the database performs the filtering and returns only objects of the requested derived type.
For example, assume that:
Class1is a base class.SomeSubClassinherits fromClass1.Class2has an association toClass1.- You need the
SomeSubClassobjects whose associatedClass2has the requested values.
Without a type filter, the query selects Class1 objects. That result can contain both SomeSubClass instances and other subclasses of Class1:
var foo2 =
from v in EcoLinqExtender.PSQuery<Class2>(EcoSpace)
where v.Class1.Attribute1 == "5" && v.Name == "5A"
select v.Class1;
Apply OfType<SomeSubClass>() to the selected result to restrict it to the derived type:
var foo2 =
(from v in EcoLinqExtender.PSQuery<Class2>(EcoSpace)
where v.Class1.Attribute1 == "5" && v.Name == "5A"
select v.Class1)
.OfType<SomeSubClass>();
The result contains only SomeSubClass instances that have an associated Class2 where Attribute1 is "5" and Name is "5A".
Why the position of OfType matters
The select v.Class1 expression has the base-class type Class1. Filtering that selected collection with OfType<SomeSubClass>() expresses both requirements:
- Find
Class2objects that match the attribute criteria. - Navigate to their
Class1association. - Keep only associated objects that are instances of
SomeSubClass.
This is the LINQ counterpart of filtering an OCL result on a type. The equivalent OCL pattern is:
Class2.allInstances
->select(a | a.Class1.Attribute1 = '5' and a.Name = '5A')
.Class1
->FilterOnType(SomeSubClass)
Use persistence-storage LINQ
PSQuery is persistence-storage (PS) LINQ: MDriven interprets the LINQ expression and sends the corresponding query to persistence storage rather than requiring all candidate objects to be loaded and filtered in memory. This is useful when the candidate set is large and you want the database to handle the criteria and type restriction.
Keep the query focused on selecting model objects. Persistence-storage LINQ has limits because it fetches objects rather than arbitrary data shapes; for example, it does not support creating tuples or many SQL functions. For broader guidance on PS queries, in-memory LINQ, and how LINQ is translated to OCL, see Documentation:A few words on linq.
Check the intended result
When adding a type filter, verify these points:
- The association being selected is declared as the base type, such as
Class1. SomeSubClassinherits from that base type.OfType<SomeSubClass>()is applied to the result of the base-type selection.- The attribute criteria remain in the
whereclause, so they are evaluated in persistence storage together with the type restriction.
