枚举字段赋值字符串时重载Setter未被调用问题咨询
Great question—this is a common gotcha when working with ORMs (especially closed-source ones) and enum-to-string conversions. Let’s break down the root causes first, then jump to actionable fixes.
Common Reasons the Overloaded Setter Fails
1. Your ORM is accessing fields directly, not properties
Most ORMs (including many custom ones) prioritize performance by writing directly to private class fields instead of calling property setters. If your enum property maps to a string-backed field, or the framework ignores setters entirely, your custom setter logic will never run.
2. You can’t overload property setters (you probably misunderstood the syntax)
Property setters don’t support parameter type overloading. If you tried something like this:
public enum Status { Active, Inactive } public class MyClass { public Status B { get; set; } // This won't work—ORM won't recognize this as a setter for B public void SetB(string value) { B = Enum.Parse<Status>(value); } }
The ORM only knows to map to the B property, not a separate SetB method. Property setters must match the property’s type exactly.
3. The ORM doesn’t support custom type conversion logic
Closed-source frameworks often lack extensibility points like type converters. If it can’t automatically convert a string to your enum, it may throw an error silently or fall back to default behavior instead of looking for your custom logic.
Fixes to Try
Choose the option that fits your framework’s capabilities:
1. Use a Type Converter (if your ORM supports it)
Many ORMs respect TypeConverter attributes to handle cross-type conversions. Create a converter for your enum, then attach it:
public class StatusConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { // Add ignoreCase if your DB values don't match enum casing return Enum.Parse<Status>(str, ignoreCase: true); } return base.ConvertFrom(context, culture, value); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string) && value is Status status) { return status.ToString(); } return base.ConvertTo(context, culture, value, destinationType); } } // Attach the converter to your enum [TypeConverter(typeof(StatusConverter))] public enum Status { Active, Inactive }
If your framework recognizes this attribute, it will automatically convert strings to/from your enum without needing custom setters.
2. Use a Backing Field + Property Wrapper
If your ORM allows mapping private fields (check its docs!), hide the string field and expose an enum property:
public class MyClass { // Tell your ORM to map this private field to the DB column private string _b; public Status B { get => Enum.Parse<Status>(_b, ignoreCase: true); set => _b = value.ToString(); } // Other properties... }
This way, the ORM writes directly to _b, and your property handles the conversion logic when you access B in code.
3. Manual Post-Fetch Conversion (Fallback Option)
If your framework is too restrictive, convert the results after fetching them:
// Keep a DB-facing class with the string property public class MyClassDb { public string B { get; set; } // Other properties... } // Your business-facing class with the enum public class MyClass { public Status B { get; set; } // Other properties... } // Fetch and convert var dbResults = YourEfMethod().ToList(); var businessResults = dbResults.Select(item => new MyClass { B = Enum.Parse<Status>(item.B, ignoreCase: true), // Map other properties here }).ToList();
This is less elegant, but it’s guaranteed to work regardless of the ORM’s limitations.
内容的提问来源于stack exchange,提问作者ajeh

