如何拦截EF操作?

时间:2015-03-18 18:54:23

标签: c# sql string entity-framework enums

我目前正在为项目使用Entity Framework,我的一个类有一个表示一些值的Enum。

到目前为止,EF将Enums保存为数据库中的数字,但我想将它们保存为实际的字符串名称。例如,Enum NY保存为1,而不是“NY”。

我已经看到了一些方法来完成这项工作,比如拥有一个带有隐藏的Enum私有字段的字符串属性,但我想知道是否有一种方法可以在执行CRUD操作时拦截EF然后我可以将Enum更改为Data Context类中的String。

1 个答案:

答案 0 :(得分:0)

不,你不能直接这样做:当你用Enum属性映射你的类时,该属性被映射到数据库int列,你不能以任何方式改变它。我的意思是,由于您无法更改模型,因此无法拦截Enum属性值并将其转换为字符串,因为模型固执地需要int

尽管如此,有几种方法可以使它发挥作用:

  • 拥有密钥的字符串属性和更新该密钥的[NotMapped] Enum属性。 请注意:但密钥必须是公开的,因此可以通过应用程序代码访问。
  • 使用仅包含enum属性并在应用程序域中使用的类,以及用于EF模型的其他类,并映射值,例如使用ValueInjecter或{{1} }

我通常采用第一个路径并使用允许我为每个Automapper值定义字符串键的属性,因此您可以在需要执行此操作的所有情况下重用此模式。

注意:答案的这一部分是错误的:您可以映射修饰符的任何属性(Enumpublicprotectedprivate。 ..)。 EF约定仅包含internal属性,并且没有可以克服此限制的数据注释。但您可以将它与Fluent API一起使用。但是,由于该属性是私有的,因此无法使用Fluent API直接访问它。这里描述了几种解决方案:Code First Data Annotations on non-public properties

如果您遵循此路径,则可以使用以下类:

public

如您所见,如果您使用这样的类,则在应用程序中,实体将具有public class MyEntity { // ... [NotMapped] public EnumType Value { get { /* return KeyForEnum converted to EnumType value */ } set { /* set KeyForEnum value from the received EnumType value*/} } // Use some mechanism to map this private property private string KeyForEnum { get; set; } // ... } 类型的属性,但在数据库中它将是一个字符串。

能够通过Fluent API映射它的一个技巧是:

1)添加一个静态属性,该属性返回一个能够从该类对象中选择属性的表达式,即

EnumType

2)在fluent API中使用它来获取映射的属性,如下所示:

public static readonly Expression<Func<MyEntity,string>> KeyForEnumExpression
   = me => me.KeyForEnum;

最后注意:这将通过添加静态readonly属性来修改POCO类。您可以使用Reflection来构建表达式来访问私有属性,就像您在此处看到的那样:EF 4.1 Code First, ¿map private members?。它是西班牙语,但您可以直接查看代码