-
Notifications
You must be signed in to change notification settings - Fork 124
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
Enums: error when dbValue doesn't exist in Enum-Values #1099
Comments
I have thought about it again. The following code should be the best. It corresponds to the C# language specification. More about this topic can be found here IsBad(Enum.IsDefined). There is also an interesting Enum-Discussion. var result = (TestEnum)reader.GetInt32(1); Solution translated to Compilerinternal static Expression ConvertExpressionToEnumExpressionForNonString(Expression expression, Type toEnumType)
{
return Expression.Convert(expression, toEnumType);
} An Enum-Option could be also conceivable
|
The following error occurs when reading a value of Enum from the DB which is not present to the target CLR Enum Type.
|
Relating: #814 |
I would like to know how to best handle this thing. Should I silently handle and pass it? Or, throw an exception like what's happening today? Or, should I introduce a new setting in the The fix is a bit simple, like simply casting it as per the 814. (see below) // Enum
public enum Gender
{
Male = 1,
Female = 2
}
// Simply cast (only for Int type)
var male = (Gender)1;
var female = (Gender)2;
var other = (Gender)3; But I guess, it would have a scenario impact to the user. |
Using GlobalConfiguration.Options.EnumHandlingpublic enum EnumHandling
{
ThrowError = 0, //Default
UseDefault = 1,
Cast = 2
}
internal static Expression ConvertExpressionToEnumExpressionForNonString(Expression expression, Type toEnumType)
{
EnumHandling handler = EnumHandling.ThrowError; //GlobalConfiguration.Options.EnumHandling
if (handler == EnumHandling.Cast)
return Expression.Convert(expression, toEnumType);
Type baseType = toEnumType.GetEnumUnderlyingType();
if (baseType != expression.Type)
{
var convertMethod = StaticType.Convert.GetMethod("ChangeType", new[] { StaticType.Object, StaticType.Type });
var convertParameters = new Expression[]
{
Expression.Convert(expression, StaticType.Object),
Expression.Constant(baseType)
};
expression = Expression.Call(convertMethod, convertParameters);
}
else
expression = Expression.Convert(expression, StaticType.Object);
var isDefinedMethod = StaticType.Enum.GetMethod("IsDefined", new[] { StaticType.Type, StaticType.Object });
var isDefinedParameters = new Expression[]
{
Expression.Constant(toEnumType),
expression
};
var isDefinedExpression = Expression.Call(isDefinedMethod, isDefinedParameters);
Expression notDefinedExpression;
if (handler == EnumHandling.UseDefault)
notDefinedExpression = Expression.Convert(Expression.Default(toEnumType), StaticType.Object);
else
{
var stringConcat = StaticType.String.GetMethod("Concat", new[] { typeof(string), typeof(string) });
var errorMessage = Expression.Call(stringConcat, Expression.Constant(toEnumType.Name + " doesn't define enum-value "), Expression.Call(expression, StaticType.Object.GetMethod("ToString")));
var argumentExceptionConstructor = typeof(ArgumentException).GetConstructor(new[] { StaticType.String });
var throwException = Expression.Throw(Expression.New(argumentExceptionConstructor, errorMessage), StaticType.Object);
notDefinedExpression = throwException;
}
var toObjectMethod = StaticType.Enum.GetMethod("ToObject", new[] { StaticType.Type, StaticType.Object });
var toObjectParameters = new Expression[]
{
Expression.Constant(toEnumType),
expression
};
var toObjectExpression = Expression.Call(toObjectMethod, toObjectParameters);
return Expression.Condition(isDefinedExpression, toObjectExpression, notDefinedExpression);
} |
Thanks for the inputs, we will consider this ;) |
#1099 Fixes to the Automatic Enum conversion for Non-Defined values.
The fixes will be available on the next release > RepoDB v1.13.0-alpha2. |
Will you be able to test the latest alpha? (Alpha 3) |
With RepoDB v1.13.0-alpha3 from nuget, I get the same error like before. But, I currently use a "fork", for fixing the errors, on my side. If I copy the code from current Compiler.cs, it works on my side. It seems, that your changes aren't included in alpha3. |
Have you tried setting the ConversionType to Automatic? I forgot to mention, the Casting and Enum Default conversion will only happen if you have set it to 'Automatic'. |
yes, I did. |
Below are the code changes made, the Integration Tests are not yet written though. Enum as String:
Enum as Int:
We tested many times and it is working? |
Oh. Looks like then, we might have built the package from the master before the actual fixes/code has been merged then. Anyway, we can issue a new alpha, or maybe promote to a beta so we can start work on our documentations. We will notify you ASAP once the new package has been pushed. |
Please use the version RepoDb v1.13.0-beta1. |
Now it works, Thanks!! |
Thanks for confirming. We can now start with the updates on the documentation and change log blogging :) |
Bug Description
I think #956 has the same problem.
If I have values in table, which doesn't exist in the given Enum, then I get the following error. I don't use string-values. I use byte, short, int, long.
Exception Message:
Model:
Compiler creates:
Expected Behaviour
return default(TestEnum)
Possible Solution
Solution translated to Compiler
Replace the following Method in Compiler.cs:
(I never used Expression before!)
Library Version:
Current master.
The text was updated successfully, but these errors were encountered: