Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在模型上使用一个布尔值来包装数据库中的字符串值?_C#_Mysql_Entity Framework Core - Fatal编程技术网

C# 如何在模型上使用一个布尔值来包装数据库中的字符串值?

C# 如何在模型上使用一个布尔值来包装数据库中的字符串值?,c#,mysql,entity-framework-core,C#,Mysql,Entity Framework Core,奇怪的问题,可能没有答案。。。我继承了一个旧的mysql数据库,不幸的是许多“布尔”字段被设置为VARCHAR,而不是更合适的TINYINT(1) 我现在在数据库上运行EntityFrameworkCore。因为我不知道布尔值在哪里使用,所以我还不能完全更新数据库,但我希望能够在EF中实际使用布尔值作为字符串是否有办法更改模型类型,使模型将所有内容整齐地包装为bool,但当我将其推送到数据库时,它仍将字段视为字符串? 本质上,在我的代码中,我希望能够做到这一点: object.IsGood=tr

奇怪的问题,可能没有答案。。。我继承了一个旧的mysql数据库,不幸的是许多“布尔”字段被设置为VARCHAR,而不是更合适的TINYINT(1)

我现在在数据库上运行EntityFrameworkCore。因为我不知道布尔值在哪里使用,所以我还不能完全更新数据库,但我希望能够在EF中实际使用布尔值作为字符串是否有办法更改模型类型,使模型将所有内容整齐地包装为bool,但当我将其推送到数据库时,它仍将字段视为字符串?

本质上,在我的代码中,我希望能够做到这一点:
object.IsGood=true
而不是:
object.IsGood=“TRUE”

我的模型将谨慎地处理值转换,类似这样的方式用于写入数据库(我需要另一个转换器来从数据库读回布尔值):


不管我怎么想,当我改变模型时,我实际上是在改变数据库。。。我知道我可以将模型本身包装到另一个类中,但这似乎令人困惑。我很想只更新数据库,但要解开所有代码可能触及这些值的地方,这可能是一个巨大的痛苦。。。所以我希望有一个中间解决方案。

我总是在“映射”或“包装器”这两个术语下搜索这类内容,而这些术语并没有从文档中找到任何有用的东西。。。克里斯托弗的评论让我走上了正确的道路,我得到了我想要的东西

很明显,“值转换”“是我想要的:

编辑:我已经删除了docs示例,因为任何人都可以查看它。我在下面添加我的真实示例

因为我想在字符串和布尔值之间来回转换,所以我将此转换器创建为静态值,以便在几个模型中重用它:

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
    );
}

这可能不是最好的解决方案,但在重构数据库之前,它可能会帮助您解决问题

向模型中添加一个分部类,并实现适当的getter和setter

partial class Model
{
    [NotMapped]
    public bool FieldABool
    {
        get
        {
            return FieldA == "TRUE";
        }
        set
        {
            if (value == true)
            {
                    FieldA = "TRUE";
            }         
            else
            {
                FieldA = "FALSE";
            }
        }
    }
}

我不知道EF的详细信息,但我认为它有一些方法可以将DB值映射到模型值。包括自定义映射。这应该在那下面。你击中了头上的钉子。。。现在看起来很傻,但我没有找到合适的术语。。。对“自定义值映射”的快速搜索带来了我想要的:添加一个带有
TINYINT
数据类型的列,然后简单地运行
更新。。。设置tinyint\u column=varchar\u column
。。。检查并删除varchar列并重命名tinyint列…应该也可以。请先对测试数据/表执行此操作。我知道并理解如何在数据库上运行值更新,如果不清楚,很抱歉。。。我避免立即这样做,因为如果我在没有首先更新代码的情况下进行更改,那么它将破坏代码。。。所以我首先需要找到使用它的代码,这将需要很长时间。。。因此,在同一时间设置转换后的EF更容易,因此我以后不必更改更多代码。也许使用MySQL视图可能更好,那么转换层在数据库中,这意味着转换后应用程序中要更改的代码更少。。iám假设实体框架核心与模型?中的源表param/变量一起工作。。你完全正确。我回去做了一些编辑,以包括我现在使用的实际代码。
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
}
partial class Model
{
    [NotMapped]
    public bool FieldABool
    {
        get
        {
            return FieldA == "TRUE";
        }
        set
        {
            if (value == true)
            {
                    FieldA = "TRUE";
            }         
            else
            {
                FieldA = "FALSE";
            }
        }
    }
}