存储bool属性为整数与Npgsql和实体框架
本文关键字:Npgsql 实体 框架 整数 bool 属性 存储 | 更新日期: 2023-09-27 18:02:29
我使用实体框架6.1与Npgsql 2.2.5驱动程序。
实体
public class MyEntity
{
public bool Deprecated { get; set; }
}
public class MyEntityMap : EntityTypeConfiguration<MyEntity>
{
public MyEntityMap ()
{
Property(t => t.Deprecated)
.HasColumnName("status")
.HasColumnType("Integer")
.IsOptional();
}
}
当我试图从数据库中读取一些东西时,我得到一个异常,这与映射的东西没有直接关系:
InvalidOperationException "Sequence doesn't contain any matching element"(翻译自德语,不知道确切的英文文本)
是否可以将布尔属性存储为整数?我做了一个变通,引入了一个int类型的新属性Status
,它被映射到status
列。然后我将NotMapped
属性添加到Deprecated
,使其返回Status != 0
作为其getter,并将Status
设置为1或0。它正在工作,但现在我不能在linq查询中使用Deprecated
。
我可以简单地更改列的数据类型,但是也有一个遗留系统使用这个数据库。引入一个新列并与一些数据库触发器保持同步是一种解决方案,但是我的模型存在一些这样的问题。所以我想要一个更一般的解。
有更好的方法吗?
是的…
我不认为有一个干净的方法来做到这一点,除非你修改源代码的npgsql EF提供程序。
public static class DbValue
{
public const int FALSE = 0; //or something like this
}
public class MyEntity
{
[Column("Deprecated")]
public integer DeprecatedStatus { get; set; }
[NotMapped]
public bool DeprecatedBool
{
get { this.DeprecatedStatus != 0 }
set { this.DeprecatedStatus = (value ? 1 : 0) }
}
}
//Then in Linq
db.MyEntities.Where(e => e.DeprecatedStatus == DbValue.FALSE);
//and
db.MyEntities.Where(e => e.DeprecatedStatus != DbValue.FALSE);
哦,嘿,我刚想到另一个主意。您可以在代码中编写表达式对象并将它们传递给您的Linq(因为IQueryable<>使用表达式)
so like this:
public class MyEntity
{
public static Expression<Func<MyEntity, bool>> IsDeprecated = (myEntity) => myEntity.Deprecated != 0;
public static Expression<Func<MyEntity, bool>> IsNotDeprecated = (myEntity) => myEntity.Deprecated == 0;
public integer Deprecated{ get; set; }
}
//Then in Linq
db.MyEntities.Where(MyEntity.IsDeprecated);
//and
db.MyEntities.Where(MyEntity.IsNotDeprecated);
使用Expressions而不是Func的原因可能会让新手有点困惑,但如果您熟悉lambda表达式,那么该模式当然很容易遵循。我以前做过这种事,很管用。不工作的是试图动态地创建表达式对象在运行时,因为在EF代码出错。(只有编译器极客才会这么做)
所以这里的缺点是每次你在LINQ中有一个表达式,你想使用Deprecated属性,你必须创建另一个静态表达式对象