奇怪的问题,也可能没有答案...我继承了一个旧的mysql数据库,不幸的是,许多"布尔"字段被设置为varchar,而不是更合适的tinyint(1(...
我现在在数据库顶部运行实体框架核心。由于我在任何地方都不知道布尔值都使用了,因此我还无法更新数据库,但是我希望能够实际使用字符串值作为EF中的布尔值... 是否有一个更改模型类型的方法,因此该模型像布尔一样整洁地包装了所有内容,但是当我将其推向数据库时,它仍然将字符视为字符串?
本质上,在我的代码中,我希望能够做到这一点: object.IsGood = true;
而不是这样:object.IsGood = "TRUE"
我的模型只会谨慎处理值转换,类似的内容是为了写入数据库(我需要另一个转换器来从数据库中读取布尔值(:
string databaseValue = "";
if (object.IsGood)
{
databaseValue = "TRUE";
}
else
{
databaseValue = "FALSE";
}
我可以看到这样做的任何方式,当我更改模型时,我实际上会更改数据库...我知道我可以将模型本身包裹在另一个类中,但这似乎令人困惑。我很想更新数据库,但这可能会造成巨大的痛苦,以揭示所有代码触及这些值的地方...所以我希望有一个中间解决方案。
我总是在"映射"或"包装器"的术语中搜索这种类型的东西,而这些东西没有从文档中提出任何有用的东西...克里斯托弗的评论使我继续正确的曲目,我得到了我正在寻找的东西。
显然" 值转换"是我正在寻找的内容:价值转换EF核心
编辑:我已经删除了文档示例,因为任何人都可以查找。我在下面添加了我的真实示例。
由于我想在字符串和布尔值之间来回转换,因此我将此转换器创建为静态值,以便我可以在几个模型中重复使用它:
public static class EntityFrameworkCoreValueConverters
{
/// <summary>
/// converts values stored in the database as VARCHAR to a nullable bool
/// handles "TRUE", "FALSE", or DBNULL
/// </summary>
public static ValueConverter<bool?, string> dbVarCharNullableToBoolNullableConverter = new ValueConverter<bool?, string>(
v => v == true ? "TRUE" : v == false ? "FALSE" : null,
v => v.ToUpper() == "TRUE" ? true : false
);
}
请注意,作为Microsoft.EntityFrameworkCore.Storage.ValueConversion
名称空间的一部分,已经存在BoolToStringConverter
,但这似乎没有处理我需要的null值。
然后,我可以将模型值更改为bool?
而不是string
,但请保留实际的数据库值类型。
然后可以在我的OnModelCreating
方法中应用dbVarCharNullableToBoolNullableConverter
(或在我的情况下,在OnModelCreating
方法中应用的模型本身Configure
:
public void Configure(EntityTypeBuilder<MachineHelpRequests> builder)
{
//... model builder code above
builder.Property(e => e.IsAcknowledged)
.HasColumnName("acknowledged_mhr")
.HasColumnType("varchar(45)")
.HasConversion(EntityFrameworkCoreValueConverters.dbVarCharNullableToBoolNullableConverter);
//... model builder code below
}
这可能不是最好的解决方案,但它可能会使您通过DB重构。
将部分类添加到模型中并实现适当的Geters和Setter。
partial class Model
{
[NotMapped]
public bool FieldABool
{
get
{
return FieldA == "TRUE";
}
set
{
if (value == true)
{
FieldA = "TRUE";
}
else
{
FieldA = "FALSE";
}
}
}
}