Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visualizer does not show expression for EF Core 5 on .NET 5 #125

Open
bart-degreed opened this issue Jul 13, 2021 · 5 comments
Open

Visualizer does not show expression for EF Core 5 on .NET 5 #125

bart-degreed opened this issue Jul 13, 2021 · 5 comments
Labels
bug Something isn't working

Comments

@bart-degreed
Copy link

I've used this visualizer a lot in the past on .NET Core 3.1 and EF Core 3.x. But today I found that when using .NET 5, binary serialization is disabled by default, which results in the next dialog when opening the visualizer from a debug session in VS 2019 v16.10.3:

image

I was able to work around that by adding this to my project file:

  <PropertyGroup>
    <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
  </PropertyGroup>

Now the visualizer loads, but it only shows the following:

image

If needed I can provide detailed repro steps, but it happens in even the simplest cases:

public class AppDbContext : DbContext
{
    public DbSet<Person> People { get; set; }
}

void Test(AppDbContext dbContext)
{
    IQueryable<Person> dataSet = dbContext.Set<Person>();
    var expr = dataSet.Expression;  // break here
}

Observed in v1.7.114.

@bart-degreed bart-degreed added the bug Something isn't working label Jul 13, 2021
@zspitz
Copy link
Owner

zspitz commented Jul 13, 2021

This is the plan.

@bart-degreed
Copy link
Author

Thanks, that seems to address the binary serialization issue.

I've been doing some more testing on EF Core 5 and run into crashes from time to time, such as KeyNotFoundException on dictionaries when type conversion expressions occur. I've never experienced such crashes before, so I think this is related to EF Core 5 and the (changes to) the way it builds expressions.

In case it helps, DebugView returns:

.Extension<Microsoft.EntityFrameworkCore.Query.QueryRootExpression>

for the NodeType: Extension error above.

@zspitz
Copy link
Owner

zspitz commented Jul 13, 2021

run into crashes from time to time, such as KeyNotFoundException on dictionaries when type conversion expressions occur

In the visualizer? Or EF Core 5?

What happens when you call Reduce?

var expr = dataSet.Expression;
while (expr.CanReduce) {
    expr = expr.Reduce();
}

@bart-degreed
Copy link
Author

In the visualizer. One such error dialog that pops up:

---------------------------
Debuggee-side exception.
---------------------------
Log message: Get response
TypeName: KeyNotFoundException
Message: The given key 'Convert(null, Person)' was not present in the dictionary.
Stack trace:
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)

   at ExpressionTreeToString.ValueExtractor.GetValue(Expression node)

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData..ctor(Object o, ValueTuple`2 path, Language language, ValueExtractor valueExtractor, Dictionary`2 pathSpans, Boolean isParameterDeclaration, PropertyInfo pi, String parentWatchExpression)

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData.<>c__DisplayClass72_0.<.ctor>b__7(String relativePath, Object o1, PropertyInfo prp)

   at ZSpitz.Util.IEnumerableTupleExtensions.<>c__DisplayClass10_0`4.<SelectT>b__0(ValueTuple`3 x)

   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData..ctor(Object o, ValueTuple`2 path, Language language, ValueExtractor valueExtractor, Dictionary`2 pathSpans, Boolean isParameterDeclaration, PropertyInfo pi, String parentWatchExpression)

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData.<>c__DisplayClass72_0.<.ctor>b__7(String relativePath, Object o1, PropertyInfo prp)

   at ZSpitz.Util.IEnumerableTupleExtensions.<>c__DisplayClass10_0`4.<SelectT>b__0(ValueTuple`3 x)

   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData..ctor(Object o, ValueTuple`2 path, Language language, ValueExtractor valueExtractor, Dictionary`2 pathSpans, Boolean isParameterDeclaration, PropertyInfo pi, String parentWatchExpression)

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData.<>c__DisplayClass72_0.<.ctor>b__7(String relativePath, Object o1, PropertyInfo prp)

   at ZSpitz.Util.IEnumerableTupleExtensions.<>c__DisplayClass10_0`4.<SelectT>b__0(ValueTuple`3 x)

   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData..ctor(Object o, ValueTuple`2 path, Language language, ValueExtractor valueExtractor, Dictionary`2 pathSpans, Boolean isParameterDeclaration, PropertyInfo pi, String parentWatchExpression)

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData.<>c__DisplayClass72_0.<.ctor>b__7(String relativePath, Object o1, PropertyInfo prp)

   at ZSpitz.Util.IEnumerableTupleExtensions.<>c__DisplayClass10_0`4.<SelectT>b__0(ValueTuple`3 x)

   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData..ctor(Object o, ValueTuple`2 path, Language language, ValueExtractor valueExtractor, Dictionary`2 pathSpans, Boolean isParameterDeclaration, PropertyInfo pi, String parentWatchExpression)

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData.<>c__DisplayClass72_0.<.ctor>b__7(String relativePath, Object o1, PropertyInfo prp)

   at ZSpitz.Util.IEnumerableTupleExtensions.<>c__DisplayClass10_0`4.<SelectT>b__0(ValueTuple`3 x)

   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData..ctor(Object o, ValueTuple`2 path, Language language, ValueExtractor valueExtractor, Dictionary`2 pathSpans, Boolean isParameterDeclaration, PropertyInfo pi, String parentWatchExpression)

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData.<>c__DisplayClass72_0.<.ctor>b__7(String relativePath, Object o1, PropertyInfo prp)

   at ZSpitz.Util.IEnumerableTupleExtensions.<>c__DisplayClass10_0`4.<SelectT>b__0(ValueTuple`3 x)

   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData..ctor(Object o, ValueTuple`2 path, Language language, ValueExtractor valueExtractor, Dictionary`2 pathSpans, Boolean isParameterDeclaration, PropertyInfo pi, String parentWatchExpression)

   at ExpressionTreeVisualizer.Serialization.ExpressionNodeData..ctor(Object o, ValueTuple`2 path, VisualizerData visualizerData, ValueExtractor valueExtractor, Dictionary`2 pathSpans, Boolean isParameterDeclaration, PropertyInfo pi, String parentWatchExpression)

   at ExpressionTreeVisualizer.Serialization.VisualizerData..ctor(Object o, Config config)

   at ExpressionTreeVisualizer.VisualizerDataObjectSource.GetResponse(Object target, Config config)

   at Periscope.Debuggee.VisualizerObjectSourceBase`2.TransferData(Object target, Stream incomingData, Stream outgoingData)

On this occasion, the DebugView property contains:

.Call System.Linq.Queryable.Where(
    .Extension<Microsoft.EntityFrameworkCore.Query.QueryRootExpression>,
    '(.Lambda #Lambda1<System.Func`2[JsonApiDotNetCoreExample.Models.TodoItem,System.Boolean]>))

.Lambda #Lambda1<System.Func`2[JsonApiDotNetCoreExample.Models.TodoItem,System.Boolean]>(JsonApiDotNetCoreExample.Models.TodoItem $todoItem)
{
    .Call ($todoItem.Description).StartsWith((.Call System.Tuple.Create("T")).Item1) && $todoItem.Priority == (.Call System.Tuple.Create(.Constant<JsonApiDotNetCoreExample.Models.TodoItemPriority>(Low))
    ).Item1 && !($todoItem.Owner == (JsonApiDotNetCoreExample.Models.Person)null) && !($todoItem.Assignee == (JsonApiDotNetCoreExample.Models.Person)null)
}

CanReduce returns false the first time, so it never enters the while loop.

@zspitz
Copy link
Owner

zspitz commented Jul 14, 2021

I've just uploaded a new release which should workaround the KeyNotFoundException. Before installing the new version, could you open a separate issue and provide a repro where you see the KeyNotFoundException dialog message?

A fix for the binary formatter is going to take a little more time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants