EF 代码生成:如何让系统枚举作为 EdmEnumType 工作?
EF code generation: How to get a System enum to work as an EdmEnumType?
我正在尝试编写自己的代码生成模板来模仿 Visual Studio 附带的 Legacy ObjectContext 模板。已经跳过了几个圈;现在我无法再与以前的代码协调一致了。
我有一个 table,其中一个字段代表 System.DayOfWeek
。但是由于我采用了“数据库优先”的方法,所以我无法将字段定义为该类型;相反,我必须定义自己的枚举类型并将其 link 定义为 System.DayOfWeek
因此:
现在我像这样设置我的字段类型:
这在遗留的 ObjectContext 模板下运行良好,因为它生成了这个:
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public DayOfWeek DayOfWeek
{
get
{
return _DayOfWeek;
}
set
{
OnDayOfWeekChanging(value);
ReportPropertyChanging("DayOfWeek");
_DayOfWeek = (DayOfWeek)StructuralObject.SetValidValue((int)value, "DayOfWeek");
ReportPropertyChanged("DayOfWeek");
OnDayOfWeekChanged();
}
}
private DayOfWeek _DayOfWeek;
partial void OnDayOfWeekChanging(DayOfWeek value);
partial void OnDayOfWeekChanged();
但缺点是我的所有代码都必须在 System.DayOfWeek
和 SchoolManagement.BL.DayOfWeek
之间进行显式转换。
现在我很兴奋,因为我的新代码模板直接将其生成为 System.DayOfWeek
,因此我不需要进行任何更显式的转换:
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public System.DayOfWeek DayOfWeek
{
get
{
return _dayOfWeek;
}
set
{
if (_dayOfWeek != value)
{
OnDayOfWeekChanging(value);
ReportPropertyChanging("DayOfWeek");
_dayOfWeek = (System.DayOfWeek)StructuralObject.SetValidValue((System.Int32)value, "DayOfWeek");
ReportPropertyChanged("DayOfWeek");
OnDayOfWeekChanged();
}
}
}
private System.DayOfWeek _dayOfWeek;
但是由于某些原因,在运行时,我一创建数据上下文,就得到一个 MetadataException
:
Schema specified is not valid. Errors:
The property 'DayOfWeek' on type 'SchoolManagement.BL.A2_SchoolHours' is attributed with EdmScalarPropertyAttribute but returns the type 'System.DayOfWeek', which is not a primitive type or a recognized enumeration type.
呃...什么? System.DayOfWeek
不是可识别的枚举类型?因此,让我们与另一个自定义枚举进行比较,就在代码的前面几行,它不会引起对元数据的任何抱怨:
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public Grade Grade
{
get
{
return _grade;
}
set
{
if (_grade != value)
{
OnGradeChanging(value);
ReportPropertyChanging("Grade");
_grade = (Grade)StructuralObject.SetValidValue((System.Byte)value, "Grade");
ReportPropertyChanged("Grade");
OnGradeChanged();
}
}
}
private Grade _grade;
在 Grade
枚举的定义中,有一个装饰器:
[EdmEnumType(NamespaceName = "SchoolManagement.BL", Name = "Grade")]
[DataContract]
public enum Grade : byte
{
我猜 EdmEnumType
是它起作用的原因。那么我如何才能将其应用于 System.DayOfWeek
?
如果您要根据现有枚举定义 EF 枚举,则不需要定义枚举值。
尝试从 "Edit Enum Type" 对话框中删除它们。
您遇到了 Entity Framework 的限制:http://connect.microsoft.com/visualstudio/feedback/details/739409/adding-enum。
如果您更改代码生成模板,您的方法将起作用:使用 DbContext 而不是 ObjectContext。
如果您想继续使用 ObjectContext,则应实施以下更改:
1) 将枚举的定义移动到包含 ObjectContext
后代的程序集中
2) 放置 EdmEnumType 属性(并设置 Name 和 NamespaceName 的值)
3) 如果需要,指定 DataContract 和 EnumMember 属性
serialization/deserialization
namespace Model {
[System.Data.Objects.DataClasses.EdmEnumTypeAttribute(Name = "Enum1", NamespaceName = "Model")]
[System.Runtime.Serialization.DataContract()]
public enum Enum1 {
[System.Runtime.Serialization.EnumMember()]
a,
[System.Runtime.Serialization.EnumMember()]
b
};
}
我正在尝试编写自己的代码生成模板来模仿 Visual Studio 附带的 Legacy ObjectContext 模板。已经跳过了几个圈;现在我无法再与以前的代码协调一致了。
我有一个 table,其中一个字段代表 System.DayOfWeek
。但是由于我采用了“数据库优先”的方法,所以我无法将字段定义为该类型;相反,我必须定义自己的枚举类型并将其 link 定义为 System.DayOfWeek
因此:
现在我像这样设置我的字段类型:
这在遗留的 ObjectContext 模板下运行良好,因为它生成了这个:
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public DayOfWeek DayOfWeek
{
get
{
return _DayOfWeek;
}
set
{
OnDayOfWeekChanging(value);
ReportPropertyChanging("DayOfWeek");
_DayOfWeek = (DayOfWeek)StructuralObject.SetValidValue((int)value, "DayOfWeek");
ReportPropertyChanged("DayOfWeek");
OnDayOfWeekChanged();
}
}
private DayOfWeek _DayOfWeek;
partial void OnDayOfWeekChanging(DayOfWeek value);
partial void OnDayOfWeekChanged();
但缺点是我的所有代码都必须在 System.DayOfWeek
和 SchoolManagement.BL.DayOfWeek
之间进行显式转换。
现在我很兴奋,因为我的新代码模板直接将其生成为 System.DayOfWeek
,因此我不需要进行任何更显式的转换:
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public System.DayOfWeek DayOfWeek
{
get
{
return _dayOfWeek;
}
set
{
if (_dayOfWeek != value)
{
OnDayOfWeekChanging(value);
ReportPropertyChanging("DayOfWeek");
_dayOfWeek = (System.DayOfWeek)StructuralObject.SetValidValue((System.Int32)value, "DayOfWeek");
ReportPropertyChanged("DayOfWeek");
OnDayOfWeekChanged();
}
}
}
private System.DayOfWeek _dayOfWeek;
但是由于某些原因,在运行时,我一创建数据上下文,就得到一个 MetadataException
:
Schema specified is not valid. Errors:
The property 'DayOfWeek' on type 'SchoolManagement.BL.A2_SchoolHours' is attributed with EdmScalarPropertyAttribute but returns the type 'System.DayOfWeek', which is not a primitive type or a recognized enumeration type.
呃...什么? System.DayOfWeek
不是可识别的枚举类型?因此,让我们与另一个自定义枚举进行比较,就在代码的前面几行,它不会引起对元数据的任何抱怨:
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public Grade Grade
{
get
{
return _grade;
}
set
{
if (_grade != value)
{
OnGradeChanging(value);
ReportPropertyChanging("Grade");
_grade = (Grade)StructuralObject.SetValidValue((System.Byte)value, "Grade");
ReportPropertyChanged("Grade");
OnGradeChanged();
}
}
}
private Grade _grade;
在 Grade
枚举的定义中,有一个装饰器:
[EdmEnumType(NamespaceName = "SchoolManagement.BL", Name = "Grade")]
[DataContract]
public enum Grade : byte
{
我猜 EdmEnumType
是它起作用的原因。那么我如何才能将其应用于 System.DayOfWeek
?
如果您要根据现有枚举定义 EF 枚举,则不需要定义枚举值。
尝试从 "Edit Enum Type" 对话框中删除它们。
您遇到了 Entity Framework 的限制:http://connect.microsoft.com/visualstudio/feedback/details/739409/adding-enum。
如果您更改代码生成模板,您的方法将起作用:使用 DbContext 而不是 ObjectContext。
如果您想继续使用 ObjectContext,则应实施以下更改:
1) 将枚举的定义移动到包含 ObjectContext
后代的程序集中2) 放置 EdmEnumType 属性(并设置 Name 和 NamespaceName 的值)
3) 如果需要,指定 DataContract 和 EnumMember 属性 serialization/deserialization
namespace Model {
[System.Data.Objects.DataClasses.EdmEnumTypeAttribute(Name = "Enum1", NamespaceName = "Model")]
[System.Runtime.Serialization.DataContract()]
public enum Enum1 {
[System.Runtime.Serialization.EnumMember()]
a,
[System.Runtime.Serialization.EnumMember()]
b
};
}