I've created a DLL in Visual Studio that holds my Entity Framework ObjectContext
. I'm trying to access its various ObjectSet
s from PowerShell. I'm doing this because I have some XML files that I'm pulling from a web service and I'd like to use PowerShell's xml features (automatic property generation, non-fatal $null evaluation) to map incoming xml values to Entities ins开发者_如何学Pythontead of having to use the C# Xml classes. Basically my PowerShell script is a data loader.
I am able to create and instantiate the ObjectContext just fine. I can see all properties using $myObjectContext | Get-Member -MemberType Property
. However, I'm having trouble understanding when exactly items get returned from queries to the ObjectSet.
I know that in Linq-to-Entities, there is lazy loading and that objects are only loaded when the collection is enumerated. I've tried calling extenion methods explicity, but it looks like PowerShell doesn't provide lambda expression support.
Here's my question. How do I know when my queries are going to be explicitly enumerated? For example, here's one of the properties (defined as ObjectSet
). <VehicleType
> VehicleTypes { get; }
PS> $myObjectContext.VehicleTypes
Produces the following error, which I'll label as (TheError) for future reference:
format-default : Exception has been thrown by the target of an invocation.
+ CategoryInfo : Not Specified: (:) [format-default], TargetInvocationException
+ FullyQualifiedErrorId : System.Reflection.TargetInvocationException
BUT, PS> $myObjectContext.VehicleTypes | Select-Object VehicleTypeID
produces the correct output (a table of VehicleTypeIDs)
However, PS> $myObjectContext.VehicleTypes | Select-Object *
gives TheError as described above.
PS> $myObjectContext.VehicleTypes | Sort-Object
always seems to enumerate the collection, which is understandable since it needs to look at all elements to compare them.
I should note that after the collection is enumerated once, calling PS> $myObjectContext.VehicleTypes
does NOT give TheError above - it display the collection exactly as you'd except. This is really weird, but I think it has something to do with lazy loading (which is why I mentioned it above).
Can anyone else confirm/explain this behavior to me, and maybe give me some pointers on best practices for using Entity Framework with PowerShell?
Also, if I do something like PS> $myObjectContext.VehicleTypes | Where-Object {$_.VehicleTypeID -eq $vehicleTypeId}
is it going to be smart enough to execute that query server side, or is it going to fetch all records from the DB and return just the one I'm looking for. If the situation is the latter, I think I might be stuck with using C# (with its not-so-friendly xml syntax) for my data access.
I can tell you that the enumeration performed by this code:
PS> $myObjectContext.VehicleTypes | Where-Object {$_.VehicleTypeID -eq $vehicleTypeId}
is all client-side.
If you want to perform native filtering, you'll need to create a cmdlet to access the data, or a provider that supports native filters.
A bit late, I realize, but TheError might be due to powershell.exe running .net v2.0. See cmo999's answer, and my own similar question.
It's possible configure powershell.exe to run under .net 4.0 by adding/modifying powershell.exe.config as described by cmo999 in the link above.
精彩评论