RepoDB: Enums: error when dbValue doesn't exist in Enum-Values
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:
System.ArgumentNullException: 'Value cannot be null. Arg_ParamName_Name'
Model:
public enum TestEnum : int
{
None = 0,
Type1 = 1
}
public class TestTable
{
public long ID { get; set; }
public TestEnum TestType { get; set; }
}
Compiler creates:
new TestTable()
{
ID = reader.GetInt64(0),
TestEnum = Convert(Parse(TestEnum, GetName(TestEnum, Convert(reader.GetInt32(1), Object)), True), TestEnum)
}
Assume reader.GetInt32(1) returns "4". But "4" doesn't exist in TestEnum. Then GetName returns "null". Parse throws the error...
Expected Behaviour return default(TestEnum)
Possible Solution
long dbValue = 4; //note, in this case the db-type differs from the corresponding enum-type int
var baseType = typeof(TestEnum).GetEnumUnderlyingType();
object convertedDbValue = dbValue;
if (baseType != dbValue.GetType()) //if dbValue-Type differs from underlying enum-type
convertedDbValue = Convert.ChangeType(dbValue, baseType); //ex. long to int
object result;
if (Enum.IsDefined(typeof(TestEnum), convertedDbValue))
result = Enum.ToObject(typeof(TestEnum), dbValue);
else
result = default(TestEnum);
return result;
Solution translated to Compiler Replace the following Method in Compiler.cs:
(I never used Expression before!)
internal static Expression ConvertExpressionToEnumExpressionForNonString(Expression expression, Type 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);
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);
var defaultExpression = Expression.Convert(Expression.Default(toEnumType), StaticType.Object);
return Expression.Condition(isDefinedExpression, toObjectExpression, defaultExpression);
}
Library Version: Current master.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 16 (11 by maintainers)
Commits related to this issue
- #1099 Fixes to the Automatic Enum conversion for Non-Defined values. — committed to mikependon/RepoDB by mikependon 2 years ago
- Merge pull request #1105 from mikependon/repodb-issue-1099 #1099 Fixes to the Automatic Enum conversion for Non-Defined values. — committed to mikependon/RepoDB by mikependon 2 years ago
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.
Using GlobalConfiguration.Options.EnumHandling