InvalidOperationException (Could not understand query) in obfuscated assembly

386 views
Skip to first unread message

Sean Kearon

unread,
May 23, 2012, 8:38:33 AM5/23/12
to rav...@googlegroups.com
My scenario is 942 running embedded in a desktop app.

I'm getting an invalid operation exception that says "could not understand query, invalid new expression".  This only happens when I run an obfuscated build, not when obfuscation is turned off then all is good.

The error happens when I'm creating an index in a background task.

I've tried everything I can think of to work this one out and am getting nowhere.  Can anyone help with this?

Details below:


Stack Trace and Error 
(obfuscation is switched to test mode where it prepends "CO_" to member names):

2012-05-23 13:28:24.7899 | Error when executing background task. | MyApp.BackgroundTask.CO_<Execute>b__1 System.InvalidOperationException: Could not understand query: 
-- line 2 col 43: invalid NewExpression

   at Raven.Database.Linq.QueryParsingUtils.GetVariableDeclarationForLinqMethods(String query, Boolean requiresSelectNewAnonymousType)
   at Raven.Database.Linq.DynamicViewCompiler.TransformMapDefinitionFromLinqMethodSyntax(String query, String& entityName)
   at Raven.Database.Linq.DynamicViewCompiler.HandleMapFunction(ConstructorDeclaration ctor, String map)
   at Raven.Database.Linq.DynamicViewCompiler.TransformQueryToClass()
   at Raven.Database.Linq.DynamicViewCompiler.GenerateInstance()
   at Raven.Database.Storage.IndexDefinitionStorage.AddAndCompileIndex(IndexDefinition indexDefinition)
   at Raven.Database.Storage.IndexDefinitionStorage.CreateAndPersistIndex(IndexDefinition indexDefinition)
   at Raven.Database.DocumentDatabase.PutIndex(String name, IndexDefinition definition)
   at Raven.Client.Embedded.EmbeddedDatabaseCommands.PutIndex(String name, IndexDefinition definition, Boolean overwrite)
   at Raven.Client.Indexes.AbstractIndexCreationTask.Execute(IDatabaseCommands databaseCommands, DocumentConvention documentConvention)
   at Raven.Client.DocumentStoreBase.ExecuteIndex(AbstractIndexCreationTask indexCreationTask)
   at Raven.Client.Indexes.AbstractIndexCreationTask.Execute(IDocumentStore store)
   at A.CO_MyApp_AppInitialiser.CO_<BackgroundLoad>b__6(Logger CO_x)
   at MyApp.BackgroundTask.CO_MyApp_BackgroundTask/<>c__DisplayClass2.CO_<Execute>b__0(Object CO_sender, DoWorkEventArgs CO_args)
   at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)

Index Class

    public class CertificateSummaryIndex : AbstractMultiMapIndexCreationTask<CertificateSummary>
    {
        public CertificateSummaryIndex()
        {
            AddMap<CertificateSummary>(certs =>
                                       from x in certs
                                       select new
                                                  {
                                                      x.Status,
                                                      x.Category,
                                                      x.TypeName,
                                                      x.LastSaved,
                                                      x.CertificateNumber,
                                                      x.CertificateId,
                                                      x.CertificateUniqueId,
                                                      x.ClientAddress,
                                                      x.ClientName,
                                                      x.DateOfCompletion
                                                  });
        }
    }

Type being Indexed

    public class CertificateSummaryIndex : AbstractMultiMapIndexCreationTask<CertificateSummary>
    {
        public CertificateSummaryIndex()
        {
            AddMap<CertificateSummary>(certs =>
                                       from x in certs
                                       select new
                                                  {
                                                      x.Status,
                                                      x.Category,
                                                      x.TypeName,
                                                      x.LastSaved,
                                                      x.CertificateNumber,
                                                      x.CertificateId,
                                                      x.CertificateUniqueId,
                                                      x.ClientAddress,
                                                      x.ClientName,
                                                      x.DateOfCompletion
                                                  });
        }
    }
This is the class being indexed:

    [Obfuscation(Exclude = true)]
    public class CertificateSummary
    {
        public string CertificateId { getset; }
        public string CertificateNumber { getset; }
        public string CertificateType { getset; }
        public string CertificateTypeDisplayName { getset; }
        public Guid CertificateUniqueId { getset; }
        public string ClientAddress { getset; }
        public string ClientName { getset; }
 
        [JsonIgnore]
        public string ClientNameAndAddress
        {
            get { return string.Join(", "new[] {ClientName, ClientAddress.ReplaceLinesBreaks(", ")}.Where(x => !string.IsNullOrEmpty(x))); }
        }
 
        public bool Completed { getset; }
        public DateTime? DateOfCompletion { getset; }
        public string FullTitle { getset; }
        public string FullTitleWithCertificateNumber { getset; }
        public string Id { getset; }
        public DateTime LastSaved { getset; }
 
        public string OccupierAddress { getset; }
        public string OccupierName { getset; }
 
        [JsonIgnore]
        public string OccupierNameAndAddress
        {
            get { return string.Join(", "new[] {OccupierName, OccupierAddress.ReplaceLinesBreaks(", ")}.Where(x => !string.IsNullOrEmpty(x))); }
        }
 
        public string Category { getset; }
        public string ReportPackName { getset; }
        public CertificateStatus Status { getset; }
        public string TypeName { getset; }
    }





Oren Eini (Ayende Rahien)

unread,
May 23, 2012, 8:50:11 AM5/23/12
to rav...@googlegroups.com
Try doing:

new CertificateSummaryIndex{ Conventions = new DocumentConventions()} .CreateIndexDefintion()

What is the value of Map?

Sean Kearon

unread,
May 23, 2012, 9:11:36 AM5/23/12
to rav...@googlegroups.com
There is no Map, I just want to search over the object.  Is that wrong?

The change to new CertificateSummaryIndex{ Conventions = new DocumentConventions()} .CreateIndexDefintion() gives this error.  I've also tried removing the index class from obfuscation, but no joy.

2012-05-23 14:06:22.0496 | Caught unhandled exception. | MyApp.Launcher.Program.HandleException System.InvalidOperationException: Could not find index named: CertificateSummaryIndex
   at Raven.Database.DocumentDatabase.<>c__DisplayClass82.<Query>b__78(IStorageActionsAccessor actions)
   at Raven.Storage.Esent.TransactionalStorage.ExecuteBatch(Action`1 action)
   at Raven.Storage.Esent.TransactionalStorage.Batch(Action`1 action)
   at Raven.Database.DocumentDatabase.Query(String index, IndexQuery query)
   at Raven.Client.Embedded.EmbeddedDatabaseCommands.Query(String index, IndexQuery query, String[] includes)
   at Raven.Client.Document.AbstractDocumentQuery`2.ExecuteActualQuery()
   at Raven.Client.Document.AbstractDocumentQuery`2.InitSync()
   at Raven.Client.Document.AbstractDocumentQuery`2.get_QueryResult()
   at Raven.Client.Linq.RavenQueryProviderProcessor`1.ExecuteQuery[TProjection]()
   at Raven.Client.Linq.RavenQueryProviderProcessor`1.Execute(Expression expression)
   at Raven.Client.Linq.RavenQueryProvider`1.Execute(Expression expression)
   at Raven.Client.Linq.RavenQueryProvider`1.System.Linq.IQueryProvider.Execute(Expression expression)
   at Raven.Client.Linq.RavenQueryInspector`1.GetEnumerator()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at MyApp.StartPage.StartPageControl.LoadContents()
   at MyApp.Controls.MainForm.<Init>b__15()
   at A.CO_MyApp_AppInitialiser.CO_DoWhen(Func`1 CO_condition, Action CO_action)
   at MyApp.Controls.MainForm.Init()
   at MyApp.Controls.MainForm.MainFormLoad(Object sender, EventArgs e)
   at System.EventHandler.Invoke(Object sender, EventArgs e)
   at System.Windows.Forms.Form.OnLoad(EventArgs e)
   at DevExpress.XtraEditors.XtraForm.OnLoad(EventArgs e)
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.WmShowWindow(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Form.WmShowWindow(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at DevExpress.XtraEditors.XtraForm.WndProc(Message& msg)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Fitzchak Yitzchaki

unread,
May 23, 2012, 9:15:35 AM5/23/12
to rav...@googlegroups.com
Can you verify that you actually have an index called CertificateSummaryIndex compiled in your assembly?
I think that the name is getting changed, and your index than have a different name, so you can't do Query<object>("CertificateSummaryIndex") since CertificateSummaryIndex isn't the index name.

Oren Eini (Ayende Rahien)

unread,
May 23, 2012, 9:14:04 AM5/23/12
to rav...@googlegroups.com
Do this as the very first line in your application:

var id = new CertificateSummaryIndex{ Conventions = new DocumentConventions()} .CreateIndexDefintion() 

MessageBox.Show(id.Map)

Sean Kearon

unread,
May 23, 2012, 9:54:21 AM5/23/12
to rav...@googlegroups.com

Looks like it is indeed being renamed.  This is the obfuscated app:

This is the non-obfuscated app:

Sean Kearon

unread,
May 23, 2012, 10:12:02 AM5/23/12
to rav...@googlegroups.com
Going to try preventing indexing of Raven.Abstractions.Indexing.IndexDefinition and see if that solves it...

Chris Marisic

unread,
May 23, 2012, 10:39:38 AM5/23/12
to rav...@googlegroups.com
Possible work arounds, any where you use the name of the index use typeof(index).Name, other options put your indexes in an assembly that is not obfuscated.

Oren Eini (Ayende Rahien)

unread,
May 23, 2012, 11:20:38 AM5/23/12
to rav...@googlegroups.com
The basic issue is that this obfuscate the name of the anonymous type, so we can't erase it.
Can you disable obfuscation of anonymous types?

Sean Kearon

unread,
May 23, 2012, 1:14:33 PM5/23/12
to rav...@googlegroups.com
Yes, you can.  Many thanks!  

There are some caveats, which I've blogged here and there's an project here.

Thanks for the speedy responses, that's really appreciated :)

Sean Kearon

unread,
May 23, 2012, 1:15:52 PM5/23/12
to rav...@googlegroups.com
Thanks Chris.  Tried the first option, but it bombs out when you try and create the index.  I'm sure the second would work...

Oren Eini (Ayende Rahien)

unread,
May 23, 2012, 1:18:07 PM5/23/12
to rav...@googlegroups.com
Sean,
While anonymous types names are an implementation detail that is theoretically subject to change. 
In practice, I doubt very much that they would be changed. That would break pretty much every linq provder out there.

Chris Marisic

unread,
May 23, 2012, 1:19:43 PM5/23/12
to rav...@googlegroups.com
Your blog needs share this or similar.

Sean Kearon

unread,
May 23, 2012, 1:24:29 PM5/23/12
to rav...@googlegroups.com
Oren - yes, that's true.  However, it's still worth noting.  Stranger things have happened :)

Chris - yes, the blog talks about the caveats.
Reply all
Reply to author
Forward
0 new messages