I'm using the AddAutoMapper method provided in the AutoMapper.Extensions.Microsoft.DependencyInjection NuGet package to setup AutoMapper into an ASP.NET Core 2.2 web app.
It works great when mapping individual entities to models and back - I can do this with no problem:
mapper.Map<Model>(context.Set<Entity>().First());
But I can't figure out how to get ProjectTo working. I'm injecting IMapper and I've tried it both of these:
mapper.ProjectTo<Model>(context.Set<Entity>());
and
context.Set<Entity>().ProjectTo<Model>(mapper.ConfigurationProvider);
I get the same error either way:
System.ArgumentException: Static method requires null instance, non-static method requires non-null instance.
at System.Linq.Expressions.Expression.ValidateStaticOrInstanceMethod(Expression instance, MethodInfo method)
at System.Linq.Expressions.Expression.ValidateMethodAndGetParameters(Expression instance, MethodInfo method)
at System.Linq.Expressions.Expression.Call(MethodInfo method, Expression arg0)
at AutoMapper.QueryableExtensions.Impl.MemberGetterExpressionResultConverter.ExpressionResolutionResult(ExpressionResolutionResult expressionResolutionResult, MemberInfo getter) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\Impl\MemberGetterExpressionResultConverter.cs:line 24
at System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable`1 source, TAccumulate seed, Func`3 func)
at AutoMapper.QueryableExtensions.ExpressionBuilder.ResolveExpression(PropertyMap propertyMap, Type currentType, Expression instanceParameter, LetPropertyMaps letPropertyMaps) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\ExpressionBuilder.cs:line 308
at AutoMapper.QueryableExtensions.ExpressionBuilder.<>c__DisplayClass17_0.<CreateMemberBindings>g__CreateMemberBinding|0(PropertyMap propertyMap) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\ExpressionBuilder.cs:line 272
at AutoMapper.QueryableExtensions.ExpressionBuilder.CreateMemberBindings(ExpressionRequest request, TypeMap typeMap, Expression instanceParameter, IDictionary`2 typePairCount, LetPropertyMaps letPropertyMaps) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\ExpressionBuilder.cs:line 266
at AutoMapper.QueryableExtensions.ExpressionBuilder.CreateMapExpressionCore(ExpressionRequest request, Expression instanceParameter, IDictionary`2 typePairCount, TypeMap typeMap, LetPropertyMaps letPropertyMaps) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\ExpressionBuilder.cs:line 204
at AutoMapper.QueryableExtensions.ExpressionBuilder.CreateMapExpression(ExpressionRequest request, IDictionary`2 typePairCount, LetPropertyMaps letPropertyMaps) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\ExpressionBuilder.cs:line 152
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at AutoMapper.QueryableExtensions.ExpressionBuilder.GetMapExpression(Type sourceType, Type destinationType, Object parameters, MemberInfo[] membersToExpand) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\ExpressionBuilder.cs:line 98
at AutoMapper.QueryableExtensions.ProjectionExpression.To[TResult](Object parameters, Expression`1[] membersToExpand) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\ProjectionExpression.cs:line 60
at AutoMapper.QueryableExtensions.Extensions.ProjectTo[TDestination](IQueryable source, IConfigurationProvider configuration, Expression`1[] membersToExpand) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\Extensions.cs:line 76
I'm trying to use it as described in the docs here:
Queryable Extensions
Static and Instance API
Dependency Injection
But it looks like I'm doing something wrong with the static vs. instance setup. I'd like to use the IMapper instance I'm passing in with DI since it works fine on single maps.
What can I do to fix this error?
I figured out the cause of this error. Thanks Lucian Bargaoanu for the reminder about the limited supported mapping options. I was using flattening with a method prefixed with “Get” on the source type, but I don't think that works with ProjectTo. (I think that falls under the last item on the list - Any calculated property on your domain object.) And that's why LINQ was giving the error "non-static method requires non-null instance."
Not sure if this'll help anyone but don't forget to check that your reverse mappings also adhere to AutoMapper's supported options.
I've just spent an hour tearing my hair out on trial-and-error attempts to fix this. Finally I noticed/remembered I had ReverseMap() at the end of all my mappings, which meant a ton of source-to-destination mapping rules were violated when the mapping was reversed.
Related
Is it possible to get call stack inside Log method of ILogger interface?
void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter);
My production code raises a few warnings(entity framework), but I am having a hard time to found sources, so I thought it would be nice if I could log file/class/method which raise the warning.
Some of the warnings:
The LINQ expression '{expression}' could not be translated and will be
evaluated locally.
Query: '{queryModel}' uses a row limiting operation (Skip/Take)
without OrderBy which may lead to unpredictable results.
I know what they mean, but I am unable to found which code (in my huge application) raises them.
As my first task working with vb.net, I was assigned the job of migrating a VB6 project over to vb.net using Visual Studio 2008. I am now working with Visual Studio 2017 and have gone through and cleared up all of the Upgrade Warnings that the conversion process gave me. The only remaining issues I have are with two instances of "Class Not Registered" Exceptions.
Things to note:
the original vb6 program was on a Windows XP machine. I am currently working on a Windows 7 64bit system.
I have read a couple of other posts here and here, but I haven't been able to solve my issue.
This warning is more specifically related to a Design view of a form
I believe the issue is probably something to do with a missing dll, as I had to move the source code to another computer to do the debugging.
Here is the call stack if anyone can help point me in the right direction:
Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
Instances of this error (2)
1. Hide Call Stack
at System.Windows.Forms.UnsafeNativeMethods.CoCreateInstance(Guid& clsid, Object punkOuter, Int32 context, Guid& iid)
at System.Windows.Forms.AxHost.CreateInstanceCore(Guid clsid)
at System.Windows.Forms.AxHost.CreateInstance()
at System.Windows.Forms.AxHost.GetOcxCreate()
at System.Windows.Forms.AxHost.set_Site(ISite value)
at System.ComponentModel.Container.Add(IComponent component, String name)
at System.ComponentModel.Design.DesignerHost.PerformAdd(IComponent component, String name)
at System.ComponentModel.Design.DesignerHost.System.ComponentModel.Design.IDesignerHost.CreateComponent(Type componentType, String name)
at System.ComponentModel.Design.Serialization.DesignerSerializationManager.CreateInstance(Type type, ICollection arguments, String name, Boolean addToContainer)
at System.ComponentModel.Design.Serialization.DesignerSerializationManager.System.ComponentModel.Design.Serialization.IDesignerSerializationManager.CreateInstance(Type type, ICollection arguments, String name, Boolean addToContainer)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeInstance(IDesignerSerializationManager manager, Type type, Object[] parameters, String name, Boolean addToContainer)
at System.ComponentModel.Design.Serialization.ComponentCodeDomSerializer.DeserializeInstance(IDesignerSerializationManager manager, Type type, Object[] parameters, String name, Boolean addToContainer)
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
at System.ComponentModel.Design.Serialization.CodeDomSerializer.DeserializeStatementToInstance(IDesignerSerializationManager manager, CodeStatement statement)
at System.ComponentModel.Design.Serialization.CodeDomSerializer.Deserialize(IDesignerSerializationManager manager, Object codeObject)
at System.Windows.Forms.Design.ControlCodeDomSerializer.Deserialize(IDesignerSerializationManager manager, Object codeObject)
at System.ComponentModel.Design.Serialization.TypeCodeDomSerializer.DeserializeName(IDesignerSerializationManager manager, String name, CodeStatementCollection statements)
Thanks for the help!
I have not used my Visual Studio 2010 for 2 weeks. Did not even touch my computer and now I am trying to work on a project.
Loaded in the project and none of the errors are shown (not even in the errorlist window). When I click build it says: build succeeded (but a bit too fast for my saying). I have tried to reload the references and even created a new project and copied the code in to it. None of this works. If I then run the project I get current error:
A first chance exception of type 'System.MissingMemberException' occurred in Microsoft.VisualBasic.dll
System.MissingMemberException: Der öffentliche Member Domains für den Typ Iref wurde nicht gefunden.
bei Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
bei Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
bei myprogram.myfunction() in projectpath/myprogram.vb:Line 132.
Iref is a reference and I am 100 procent sure that the Domains member still exists in this reference.
Anyone have any ideas how I can fix this?
Fixed this by putting on the Option Strict to ON.
Not really the best solution but will do for the meanwhile
I encountered the same problem. I solved this by changing the Active Solution Platform to Mixed Platform. To do so, go to Configuration Manager and set the Active Solution Platform in the upper right corner.
I'm working with a S#arp Architecture project that includes some database Tasks that have worked in the past. Specifically:
var principals = _principalTasks.GetAll().AsPagination(page, limit);
where the task is defined as:
public IQueryable<Principal> GetAll()
{
return _principalRepository.FindAll().OrderBy(o => o.PrincipalName.ToLower());
}
This is effectively using NHibernate.Linq.
This is using the DB2400Dialect. Now it throws:
System.NotSupportedException: Dialect does not support variable limits.
at NHibernate.Dialect.Dialect.GetLimitString(SqlString queryString, Nullable`1 offset, Nullable`1 limit, Parameter offsetParameter, Parameter limitParameter)
at NHibernate.Hql.Ast.ANTLR.SqlGenerator.GetSqlStringWithLimitsIfNeeded(QueryWriter queryWriter)
at NHibernate.Hql.Ast.ANTLR.SqlGenerator.EndQuery()
at NHibernate.Hql.Ast.ANTLR.SqlGenerator.selectStatement()
at NHibernate.Hql.Ast.ANTLR.SqlGenerator.statement()
at NHibernate.Hql.Ast.ANTLR.HqlSqlGenerator.Generate()
.
.
.
It looks like the SQLGenerator insists on parameterizing the skip and take parameters which this dialect does not support.
Is there a way around this or is this an NHibernate bug?
EDIT:
BTW, this is the Expression Debug string from the NHibernate.Linq.DefaultQueryProvider call:
.Call System.Linq.Queryable.Take(
.Call System.Linq.Queryable.Skip(
.Call System.Linq.Queryable.OrderBy(
.Constant<NHibernate.Linq.NhQueryable`1[SolutionExample.Domain.Principal]>(NHibernate.Linq.NhQueryable`1[SolutionExample.Domain.Principal]),
'(.Lambda #Lambda1<System.Func`2[SolutionExample.Domain.Principal,System.String]>)),
0),
25)
.Lambda #Lambda1<System.Func`2[SolutionExample.Domain.Principal,System.String]>(SolutionExample.Domain.Principal $o) {
.Call ($o.PrincipalName).ToLower()
}
After much research I've decided that while I could solve this question by either creating my own custom dialect that implements - or extending the existing DB2400Dialect to implement -
public SqlString GetLimitString(SqlString queryString, int? offset, int? limit, Parameter offsetParameter, Parameter limitParameter)
that would be pointless since while the iSeries allows a limit with the
... FETCH FIRST n ROWS ONLY
syntax, it has no equivalent syntax for doing an offset... so, there isn't much point to fixing the broken bits.
There are issue with using WebBrowser late bind calls related to object/property names generation.
For example:
WebBrowser1.Document.DomDocument.Forms.Myform.mycontrol.Value = "test"
will fail with more than one instance of the WebBrowser control
what actually happen is that mycontrol object become Mycontrol and compiled vb.net application will fail with error
Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))
at Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType,
String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance,
Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames,
Type[] TypeArguments, Boolean[] CopyBack)
at Execute() in C:\Projects\WebBrowser\SampleCall.vb:line 16
Is there are any solutions for this issue?
Same code will work with vb6 app with multiple WebBrowser controls
Edit: This code is comipled with: Option Strict Off
#bugtussle
Next assignments will work:
WebBrowser1.Document.Forms("Myform").Children("mycontrol").InnerText = "test"
WebBrowser1.Document.DomDocument.Forms("Myform").all("mycontrol").Value = "test"
WebBrowser1.Document.DomDocument.Forms.Myform.all.mycontrol.Value = "test"
The problem with this approach that is required to change and retest a lot of code
If you take a look into Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet method using reflector utility, you can find that BindingFlags.IgnoreCase flag is used in binder.InvokeMember call.
I do undestant that this call is done through COM, and was reading somewhere that COM interop is using one version of name in a lookup table. Like if parameter name was initially entered into that table as "MyControl" than this version will be used, not "mycontrol". I think because of that later on InvokeMember is failing to find correct member.
Try setting the value a different way:
WebBrowser1.Document.Forms("Myform").children("mycontrol").Value = "test"