Exception when I use Count method in Queryable class - c#

In WinRT when I call the count method in Queryable class for the IOrderedEnumerable instance it will throw the exception.
DoWork(emp); //Working fine
DoWork(emp.OrderBy(objects => objects.EmployeeId)); //throw exception..
public void DoWork(IEnumerable<object> collection)
{
var queryable = collection.AsQueryable();
int count = 0;
if (queryable != null)
count = queryable.Count();
else
throw new InvalidOperationException("Not able to get count");
//Some other operations using queryable...
}
Exception
System.InvalidOperationException was unhandled by user code
HResult=-2146233079
Message=The API 'System.Linq.OrderedEnumerable`2[[SfDataGrid.BusinessObjects, SfDataGrid, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' cannot be used on the current platform. See http://go.microsoft.com/fwlink/?LinkId=248273 for more information.
Source=mscorlib
StackTrace:
at System.Reflection.Emit.DynamicILGenerator.GetTokenFor(RuntimeType rtType)
at System.Reflection.Emit.DynamicILGenerator.Emit(OpCode opcode, Type type)
at System.Linq.Expressions.Compiler.BoundConstants.EmitConstantFromArray(LambdaCompiler lc, Object value, Type type)
at System.Linq.Expressions.Compiler.BoundConstants.EmitConstant(LambdaCompiler lc, Object value, Type type)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitConstant(Object value, Type type)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitConstantExpression(Expression expr)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitExpression(Expression node, CompilationFlags flags)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitArguments(MethodBase method, IArgumentProvider args, Int32 skipParameters)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitMethodCall(MethodInfo mi, IArgumentProvider args, Type objectType, CompilationFlags flags)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitMethodCall(Expression obj, MethodInfo method, IArgumentProvider methodCallExpr, CompilationFlags flags)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitMethodCallExpression(Expression expr, CompilationFlags flags)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitExpression(Expression node, CompilationFlags flags)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitLambdaBody(CompilerScope parent, Boolean inlined, CompilationFlags flags)
at System.Linq.Expressions.Compiler.LambdaCompiler.EmitLambdaBody()
at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
at System.Linq.EnumerableExecutor`1.Execute()
at System.Linq.EnumerableQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
at SfDataGrid.ViewModel.GetCount(IEnumerable`1 collection) in e:\DiskD\Support\I108101\SfDataGrid1022101733\SfDataGrid\SfDataGrid\ViewModel\ViewModel.cs:line 39
at SfDataGrid.ViewModel..ctor() in e:\DiskD\Support\I108101\SfDataGrid1022101733\SfDataGrid\SfDataGrid\ViewModel\ViewModel.cs:line 27
at SfDataGrid.SfDataGrid_XamlTypeInfo.XamlTypeInfoProvider.Activate_0_ViewModel() in e:\DiskD\Support\I108101\SfDataGrid1022101733\SfDataGrid\SfDataGrid\obj\Debug\XamlTypeInfo.g.cs:line 123
at SfDataGrid.SfDataGrid_XamlTypeInfo.XamlUserType.ActivateInstance() in e:\DiskD\Support\I108101\SfDataGrid1022101733\SfDataGrid\SfDataGrid\obj\Debug\XamlTypeInfo.g.cs:line 3679

It seems that IOrderedEnumerable<T>.AsQueryable() is implemented using dynamic code generation which is not available in WinRT. You could work around that by materializing it in a list before calling AsQueryable():
public void DoWork(IEnumerable<object> collection)
{
var queryable = collection.ToList().AsQueryable();
int count = 0;
if (queryable != null)
count = queryable.Count();
else
throw new InvalidOperationException("Not able to get count");
//Some other operations using queryable...
}
Unless you're working with very large collections performance shouldn't be much worse.

You must use IOrderable<object> instead of IEnumerable<object> as param for DoWork Method
IOrderable:
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.utilities.iorderable.aspx
IEnumerable:
http://msdn.microsoft.com/en-us/library/system.collections.ienumerable(v=vs.100).aspx

Related

Duplicate type name within an assembly (with NSubstitute)

Since this morning, our CI build failed due to surprising "System.ArgumentException : Duplicate type name within an assembly." exceptions during our tests execution.
(note: our tests project built in .NET (4.6) using references to NUnit (3.9.0.0) and NSubstitute (3.1.0.0).
So far we have step into mscorlib (ModuleBuilder type) and found out that Castle.DynamicProxy was dynamically generating an assembly to host its stubs/fakes/ named: DynamicProxyGenAssembly2. And it seems that we had more than one reference for type named "Castle.Proxies.IEnumerator`1Proxy_13".
We don't really understand what's going on here. We appreciate any suggestion on how to understand and find out a solution.
Stack trace example: -----------------
at System.Reflection.Emit.ModuleBuilder.CheckTypeNameConflict(String strTypeName, Type enclosingType)
at System.Reflection.Emit.AssemblyBuilderData.CheckTypeNameConflict(String strTypeName, TypeBuilder enclosingType)
at System.Reflection.Emit.TypeBuilder.Init(String fullname, TypeAttributes attr, Type parent, Type[] interfaces, ModuleBuilder module, PackingSize iPackingSize, Int32 iTypeSize, TypeBuilder enclosingType)
at System.Reflection.Emit.ModuleBuilder.DefineTypeNoLock(String name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packingSize, Int32 typesize)
at System.Reflection.Emit.ModuleBuilder.DefineType(String name, TypeAttributes attr)
at Castle.DynamicProxy.Generators.Emitters.ClassEmitter..ctor(ModuleScope modulescope, String name, Type baseType, IEnumerable1 interfaces, TypeAttributes flags, Boolean forceUnsigned)
at Castle.DynamicProxy.Generators.Emitters.ClassEmitter..ctor(ModuleScope modulescope, String name, Type baseType, IEnumerable1 interfaces)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.BuildClassEmitter(String typeName, Type parentType, IEnumerable1 interfaces)
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.Init(String typeName, ClassEmitter& emitter, Type proxyTargetType, FieldReference& interceptorsField, IEnumerable1 interfaces)
at Castle.DynamicProxy.Generators.InterfaceProxyWithoutTargetGenerator.GenerateType(String typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.<>c__DisplayClass6_0.b__0(String n, INamingScope s)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func3 factory)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.GenerateProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
at NSubstitute.Core.SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments, SubstituteConfig config)
at NSubstitute.Routing.Handlers.ReturnAutoValue.<>c__DisplayClass6_0.<ReturnValueUsingProvider>b__0(IAutoValueProvider provider)
at NSubstitute.Routing.Handlers.ReturnAutoValue.Handle(ICall call)
at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1 source, Func2 predicate)
at NSubstitute.Routing.Route.Handle(ICall call)
at NSubstitute.Proxies.CastleDynamicProxy.CastleForwardingInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.IEnumerable1Proxy_16.GetEnumerator()
at System.Linq.Buffer1..ctor(IEnumerable1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source)
at Caraibes.Infrastructure.AggregateCreationAuditTrail.BuildCacheFromEventStore(AggregateType aggregateType) in E:\Builds\TheFuture01_work\366\s\Caraibes\Caraibes.Infrastructure\AggregateCreationAuditTrail.cs:line 45
at Caraibes.Infrastructure.AggregateCreationAuditTrail.HasAlreadyBeenCreated(AggregateType aggregateType, Int32 lightTradeId) in E:\Builds\TheFuture01_work\366\s\Caraibes\Caraibes.Infrastructure\AggregateCreationAuditTrail.cs:line 31
at Caraibes.Tests.Domain.EventSourcing.AggregateCreationAuditTrailShould.Only_call_EventStore_when_previous_request_did_not_contained_the_requested_identifier(AggregateType aggregateType) in E:\Builds\TheFuture01_work\366\s\Caraibes\Caraibes.Tests\Domain\EventSourcing\AggregateCreationAuditTrailShould.cs:line 74
Attachments (0)

Reflection GetMethod with a type paramenter

The following line is not running properly, and I'm not sure why. The Error:
System.Reflection.TargetParameterCountException: parameters do not match signature
And the line of code in question:
typeof(Resources).GetMethod("LoadAll", new Type[] { typeof(System.String), typeof(System.Type)});
Displaying all functions of the Resources class shows:
UnityEngine.Object[] FindObjectsOfTypeAll(System.Type)
T[] FindObjectsOfTypeAll[T]()
UnityEngine.Object Load(System.String)
T Load[T](System.String)
UnityEngine.Object Load(System.String, System.Type)
UnityEngine.ResourceRequest LoadAsync(System.String)
UnityEngine.ResourceRequest LoadAsync[T](System.String)
UnityEngine.ResourceRequest LoadAsync(System.String, System.Type)
UnityEngine.Object[] LoadAll(System.String, System.Type)
UnityEngine.Object[] LoadAll(System.String)
T[] LoadAll[T](System.String)
UnityEngine.Object GetBuiltinResource(System.Type, System.String)
T GetBuiltinResource[T](System.String)
Void UnloadAsset(UnityEngine.Object)
UnityEngine.AsyncOperation UnloadUnusedAssets()
Boolean Equals(System.Object)
Int32 GetHashCode()
System.Type GetType()
System.String ToString()
System.Reflection.MethodInfo[]
I'm trying to match UnityEngine.Object[] LoadAll(System.String, System.Type). Any thoughts on what may be the issue?
Bonus if you can make a line that returns a methodinfo object for "T[] LoadAllT", specific to a given type.
The issue is that you are trying to get an instance level method while the LoadAll is static.
Try this one:
typeof(Resources).GetMethod("LoadAll",
System.Reflection.BindingFlags.Static,
new Type[] { typeof(System.String),typeof(System.Type)},
null);

PropertyInfo.SetValue ArgumentException?

I have the following code. However, it has a runtime exception on SetValue. What may cause the error?
var _filter = new Filter(....); // Filter implemented IFilter
ApplyFilter(_view.Name, x => x.Name);
private void ApplyFilter<T>(T curr, Expression<Func<IFilter, T>> prev)
{
var expr = (MemberExpression)prev.Body;
var prop = (PropertyInfo)expr.Member;
if (!EqualityComparer<T>.Default.Equals(curr, (T)_filter[prop.Name]))
{
prop.SetValue(_filter, curr, null); // Error
..... // do something on _filter
The exception is:
System.ArgumentException was unhandled
Message=Property set method not found.
Source=mscorlib
StackTrace:
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
at MyApp.ErrorLogPresenter.ApplyFilter[T](T curr, Expression`1 prev) in d:\....cs:line 50
Message=Property set method not found.
This usually simply means that the property you are using does not define a setter. Either ensure that a suitable setter exists, or use a different approach to assign values.

Serialize a Dictionary<string, object> that contains a List<string>?

I've found a Serializeable Dictionary which works quite fine: http://www.jankowskimichal.pl/en/2010/10/serializabledictionary/
But I'm getting an exception whenever one of the objects in the dictionary is simply a list of strings. .NET is telling me it can't serialize it:
Serialize 'C:\bin\Debug\Settings\Default.xml' : System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] may not be used in this context.
at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterObject.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterObject.Write2_anyType(Object o)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o)
at ShadowBot.Classes.SerializableDictionary`2.WriteXml(XmlWriter writer) in c:\Classes\SerializableDictionary.cs:line 114
at System.Xml.Serialization.XmlSerializationWriter.WriteSerializable(IXmlSerializable serializable, String name, String ns, Boolean isNullable, Boolean wrapped)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterShadowSettings.Write2_ShadowSettings(String n, String ns, ShadowSettings o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterShadowSettings.Write3_ShadowSettings(Object o)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o, XmlSerializerNamespaces namespaces)
at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o)
at Classes.XmlSerializer.Serialize(String Path, Object Object) in c:\Classes\XmlSerializer.cs:line 29
Is this even possible? I'd like this capability and just assumed you could nest objects like this. If this isn't possible, is there a way I can just write the dictionary to disk (doesn't have to be XML) and then re-load it without me having to write custom wrappers for this? I was originally a mac developer and this type of serialization was quite simple, so maybe I'm missing something on .NET.
Edit: When trying odyss' example i get:
System.Runtime.Serialization.SerializationException: Type 'System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' with data contract name 'ArrayOfstring:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
I've had similar issues with serializing generic lists. Try changing the list into an string array string[] before serializing and then back to a List<string> after deserializing. This is very easy to do and may solve your problem:
//List<string> to string[]
string[] sArray = sList.ToArray();
//string[] to List<string>
List<string> sList = sArray.ToList();
As an alternative, you might have better luck with System.Runtime.Serialization.DataContractSerializer. Example:
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();
dict.Add("test", new List<string>() { "t", "b" });
StringBuilder xmlString = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(xmlString))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, List<string>>));
serializer.WriteObject(writer, dict);
}
This generates:
<?xml version="1.0" encoding="utf-16"?><ArrayOfKeyValueOfstringArrayOfstringty7Ep6D1 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><KeyValueOfstringArrayOfstringty7Ep6D1><Key>test</Key><Value><string>t</string><string>b</string></Value></KeyValueOfstringArrayOfstringty7Ep6D1></ArrayOfKeyValueOfstringArrayOfstringty7Ep6D1>

C# Reflection SetValue() can not find set accessor

I use reflection to update objects which have had updates made to them and saved to mongodb
private void updateSelf(MongoDoc newDoc)
{
Type type = this.GetType();
foreach (var i in type.GetProperties())
{
if (i.GetCustomAttributes(false).Any(x => x is MongoDB.Bson.Serialization.Attributes.BsonIgnoreAttribute)) continue;
Object oldValue = i.GetValue(this, null);
Object newValue = i.GetValue(newDoc, null);
if (!Object.Equals(oldValue, newValue) && !((oldValue == null) && (newValue == null)))
{
i.SetValue(this, newValue, null);
}
}
}
this is working for the most part but the i.SetValue(this, newValue, null); throws an exception when trying to update this property:
public uint Revision { get; private set; }
this is trying to update an object of type Product which is a derived type of MongoDoc which contains the property public uint Revision { get; private set; } which is causing the exception Property set Method not found I'm not sure what is causing this because it works on all my other properties, just this one throws and exception. Any help much appreciated
UPDATE:
I have tried the answer below:
i.SetValue(this, newValue, System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, null, null, null);
but unfortunately the exact same result, it still throws the exception on the Revision property.
UPDATE:
Exception:
System.ArgumentException was unhandled
Message=Property set method not found.
Source=mscorlib
StackTrace:
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
at Flo.Client.Docs.MongoDoc.updateSelf(MongoDoc newDoc) in F:\Flo\Flo.Client\Docs\MongoDoc.cs:line 162
at Flo.Client.Docs.MongoDoc.UpdateToMongo(MongoDoc newDoc) in F:\Flo\Flo.Client\Docs\MongoDoc.cs:line 120
at Flo.Client.Docs.Product.EditProduct(String Name, Nullable`1 State) in F:\Flo\Flo.Client\Docs\Product.cs:line 89
at Flo.Client.Program.Main() in F:\Flo\Flo.Client\Program.cs:line 26
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
I fixed it with this, thanks to Dylan Meador for pointing me to another question which gave me enough to get the solution:
private void updateSelf(MongoDoc newDoc, Type type)
{
foreach (var i in type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public))
{
if (i.GetCustomAttributes(false).Any(x => x is MongoDB.Bson.Serialization.Attributes.BsonIgnoreAttribute)) continue;
Object oldValue = i.GetValue(this, null);
Object newValue = i.GetValue(newDoc, null);
if (!Object.Equals(oldValue, newValue) && !((oldValue == null) && (newValue == null)))
{
i.SetValue(this, newValue, null);
}
}
Type baseType = type.BaseType;
if (baseType != null)
{
this.updateSelf(newDoc, baseType);
}
}
It looks like the Type needed to be explicitly set to the base class type in order to use the set accessor for that particular property.
Try using the overload of SetValue that has an System.Reflection.BindingFlags parameter and pass it a value of BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.NonPublic.
The problem is that from the point of view of the derived type there is no setter for the property.
You can work around this walking the inheritance hierarchy and getting the properties declared on each type (using the DeclaredOnly BindingFlag, together with Public and Instance), or checking whether the property is declared by the reflection type and if not get it again from the property info's DeclaringType.
For the former you'd you could have a nested loop, while the latter would look something like this:
foreach (var property in p.GetType().GetProperties())
{
var actualProperty = property.DeclaringType != property.ReflectedType ? property.DeclaringType.GetProperty(property.Name) : property;
actualProperty.SetValue(p, newValue, null);
}
Probably the issue can be in next:
You are using auto property
public uint Revision { get; private set; }
Which perform boxing/unboxing operations through default type int.
So, here you should explicitly cast to uint type.
You can find out similar problem with next snippet:
byte b1 = 4;
byte b2 = 5;
byte sum = b1 + b2;
This will raise an exception since no overload are declared for "+" operator.
This snippet actually demonstrate an issue with boxing/unboxing operations through default type int.

Categories