Converting ParserRuleContext to a child context - antlr

I have a Visit method generated from the Rule below:
statement
: labeled_Statement
| declarationStatement
| embedded_statement
;
I'm only interested in processing the embedded_statement so I tried the following, but getting an error shown below.
What's the proper way to convert the ParserRuleContext to a child's context to call a child Visit method?
public override object VisitStatement(CSharpParser.StatementContext context)
{
// return VisitChildren(context);
if (context.embedded_statement() != null)
return VisitEmbedded_statement(context); // Argument 1: cannot convert from 'CSharpParser.StatementContext' to 'CSharpParser.Embedded_statementContext'
else
return null;
}

Related

Error, Must specify valid information for parsing in the string, when using EF Core Value Conversion

Based on the EF Core docs (https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions), I'm trying to use EF Core's new Value Conversion on an enumeration. I want to save the enumeration as a string in the SQL Database table.
Here's the entity and enumeration.
public enum InputSetType
{
TypeA, TypeB
}
public class MonthlyInputSet
{
public int Id { get; set; }
public InputSetType Type { get; set; }
}
Here is where I configure the MonthlyInputSet Entity:
public class MonthlyInputSetConfiguration : IEntityTypeConfiguration<MonthlyInputSet>
{
public void Configure(EntityTypeBuilder<MonthlyInputSet> builder)
{
builder.Property(mis => mis.Type).HasConversion(v => v.ToString(), v => (InputSetType)Enum.Parse(typeof(InputSetType), v));
}
}
So, I try to run a basic query to get this data and it fails. The query is:
var saved = await _context.MonthlyInputSets.Include(mis => mis.InsertedBy)
.Include(mis => mis.UpdatedBy)
.Include(mis => mis.MonthlyInputs)
.ThenInclude(mi => mi.EmissionsUnit)
.FirstOrDefaultAsync(mis => mis.Id == id);
But, an error is thrown on the first line of this query that says, "ArgumentException: Must specify valid information for parsing in the string." So my guess is that I have not properly configured the conversion of the string in the table to the enum in C#.
Full raw stack trace:
I verified that the correct string value is being returned from the database. It is not null and it is not a blank string. The string value returned matches a member of the enum perfectly.
public void Configure(EntityTypeBuilder<MonthlyInputSet> builder)
{
builder.Property(mis => mis.Type).HasConversion(
convertToProviderExpression: v => v.ToString(),
convertFromProviderExpression: v => Troubleshooting(v)
);
}
private InputSetType Troubleshooting(string v)
{
return (InputSetType)Enum.Parse(typeof(InputSetType), v);
}
these two images show that the text in every row in the database type column is identical to the 2nd member of the enum that is mapped to this field.
The only way I can reproduce this error is for v to be an empty string, ie "". Not a null.
This :
Enum.Parse(typeof(InputSetType),"xx")
Throws Requested value 'xx' was not found..
While this:
Enum.Parse(typeof(InputSetType),"")
Throws :
Must specify valid information for parsing in the string. (Parameter 'value')
It seems some rows contain an empty string instead of null.
You'll have to decide what to do with those values - are they bad data? Or should the application handle them and replace them with some default value?
If you decide to use a default value you could use String.IsEmptyorString.IsNullOrWhitespace` to handle them, eg:
v=> String.NullOrWhitespace(v)?InputSetType.Unknown:Enum.Parse(typeof(InputSetType),v)
Probably this exception is caused by invalid data in the database - data, that is not present in the enum, null, empty string or so on. This error is common in Enum.Parse() so I think it is related to this method.

Expression Parameter is not displayed in generated Swagger documentation

I have a Controller that has has a parameter of type Expression<Foo, bool> with the name query however that parameter does not show up in the generated swagger.json file. Instead a lot (>1000) parameters that have names like these show up:
Body.CanReduce
ReturnType.IsGenericMethodParameter
Type.IsGenericType
I would like to tell SwaggerGen to have my parameter just shown up as a string. If it is possible using a Filter, that would be my preferred way, but an Attribute would be fine too.
I already tried using an IOperationFilter, but it did not work as operation.Parameters does not even seem to have a paramater with the name query.
private static readonly Type _expressionType = typeof(Expression);
public void Apply(Operation operation, OperationFilterContext context)
{
foreach (var parameter in context.ApiDescription.ActionDescriptor.Parameters)
{
if(_expressionType.IsAssignableFrom(parameter.ParameterType))
{
// The parameter is found ...
var expressionParameter = operation.Parameters.FirstOrDefault(p => p.Name == parameter.Name);
if (expressionParameter != null)
Debugger.Break(); // ... but is not in the operation.Parameters collection although the >1000 mentioned above are.
}
}
}
P.S. to anyone interested: I'm using a custom ModelBinder and System.Linq.Dynamic to parse a query string to an Expression<Foo, bool>

Return multiple validation failures from a single Custom() rule?

Using FluentValidation and a Custom() rule, I want to be able to validate a collection of child objects, and return a ValidationFailure for each child object that is invalid.
I can't use a collection validator because the child object doesn't contain the right information to execute the rule - it must run in the context of the parent.
However the Custom() API limits me to returning a single ValidationFailure or nothing at all.
Is there a pattern I can use that allows a single rule to generate multiple errors?
I found a good solution - use AddRule() with a DelegateValidator.
public MyValidator : AbstractValidator<MyClass>
{
public MyValidator()
{
AddRule(new DelegateValidator<MyClass>(MyRule));
}
private IEnumerable<ValidationFailure> MyRule(
MyClass instance,
ValidationContext<MyClass> context)
{
var result = new List<ValidationFailure>();
// add as many failures to the list as you want:
var message = "This is not a valid message";
result.Add(new ValidationFailure(nameof(MyClass.SomeProperty), message));
return result;
}
}

Rest Sharp Execute<Int> fails due to cast exception

I have this:
public Int32 NumberOfLocationsForCompany(int companyId)
{
var response = _curl.ResetRequest()
.WithPath(LOCATION_URL)
.AddParam("companyId", companyId.ToString())
.RequestAsGet()
.ProcessRequest<Int32>();
return response;
}
that calls this at the end.
public T ProcessRequest<T>() where T : new()
{
var response = _client.Execute<T>(_request);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
return response.Data;
}
but I get this error. I don't get why it's trying to map an int to a collection or why it's Int64 vs the 32 I specified.: Unable to cast object of type 'System.Int64' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.
When I hit the api directly this is what I get back
<int xmlns="http://schemas.microsoft.com/2003/10/Serialization/">17</int>
I feel it's something I'm not understanding about Rest Sharp. I tell the execute method to expect an Int, it receives and int, but is trying to map it to a collection. Why and where does the collection come from?
I have noticed that when I look into the base response object's Content the appropriate result "17" is present, why can't Rest Sharp find it? and still where is it finding the Collection?
When looking at the response object I found the return value was in Content vs in Data. I found this to be true whenever I was not returning an object or list of objects.
So now when I'm expecting an int, string, bool, etc I use the following and cast the type of the return value:
public string ProcessRequestWithValue()
{
var response = _client.Execute(_request);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
return response.Content;
}
Hope this helps!

NHibernate: Setting up references with IResultTransformer

I have a custom class that implements IResultTransformer.
It is easy to make this work for single values but what is the correct way to setup references if only the id is in the tuple? What if they are supposed to be lazy loaded? Should I just load them from the Session using the Get or Load methods?
For example:
public class FoobarResultTransformer : IResultTransformer
{
public object TransformTuple(object[] tuple, string[] aliases)
{
var foobar = new Foobar();
for (int i = 0; i < aliases.Length; i++)
{
switch(aliases[i])
{
case "IntProperty":
// This one is easy
foobar.IntProperty = Convert.ToInt32(tuple[i]);
break;
case "ReferencedEntityId":
// Assuming the tuple contains a GUID identifier, what should I do here?
foobar.ReferencedEntity =
break;
}
}
return foobar;
}
}
You should load the referred entity by its primary key using Get or Load. If they should be lazy loaded, use Load.
Get will return null if the object does not exist. This usually results in a select against the database, but it will check the session cache and the 2nd level cache first.
Load will never return null. It will return a proxy.