将 Y/N 属性映射到布尔值而不破坏实体链接

问题描述 投票:0回答:3

好的,我正在使用一个旧的 SQL 数据库,它太旧了,以至于最初您无法索引位字段。 所以我有一堆表,其中包含 Y/N 单字符字段。

我终于有机会将东西转移到 C# 和实体框架中。

如果能够在前端将它们“转换”为布尔字段,那将非常方便。 但是当我这样做时,当我查询 Linq to Entities 时,我会破坏它。

例如

db.Carriers.Where(x => x.ActiveBool) 死亡。

db.Carriers.ToList().Where(x => x.ActiveBool) 没有。 但显然,没有查询回 SQL 等

有没有办法实现其中之一(或其他聪明/方便的方法)

  1. 进行属性映射以将字段视为布尔值
  2. 做一个我可以使用的“适当的”新财产
  3. 在我可以调用的对象上添加一个不会破坏 Linq to Entities 的方法
.net entity-framework-6 linq-to-entities
3个回答
2
投票

您有几个选择。如果可以的话,您可以更新数据库以具有计算字段,然后您可以以这种方式查询它。

您可以为 IsActive 创建一个 [NotMapped] 属性来执行以下操作:

[NotMapped]
public bool IsActive 
{ 
    get { return Active == 'Y'; } 
    set { Active = value ? 'Y' : 'N'; } 
}

然后,您可以将“Active”字段设置为Internal,使其指向数据库,但仅适用于模型上的此IsActive列。

但是,为了实际过滤该字段,您必须使用计算列、视图,或者将从上面传入的 IsActive 布尔过滤器转换为“Y”或“N”。否则,您可以在幕后做一些棘手的表达式工作,为您进行此转换,但我认为不值得付出这种努力。一个辅助方法可能就可以了。

char check = Helper.ConvertBoolToChar(entity.IsActive) (returns 'Y' or 'N')
...Where(a => a.Active == check)

0
投票

好的。我想我至少得到了部分解决方案。

添加到(例如单位类)

       public static System.Linq.Expressions.Expression<Func<Units, bool>> IsActive = x => ("Y".Equals(x.Active, StringComparison.OrdinalIgnoreCase)) && 
(x.Carriers == null || "Y".Equals(x.Carriers.Active, StringComparison.OrdinalIgnoreCase));

然后过滤

   l = l.Where(Data.Units.IsActive);

我不知道如何在“a”上执行 WHERE 引用导航对象“a.B”作为单独的步骤,但这应该可以满足我的需要。 是时候测试一下了。

是的。这似乎有效。


0
投票

您可以使用 TypeHandler。我只在读取数据时对此进行了测试,但这对我有用。

public class YnToBoolTypeHandler : SqlMapper.TypeHandler<bool>
{
    public override bool Parse(object value) => "Y" == (string?)value;

    public override void SetValue(IDbDataParameter parameter, bool value)
    {
        parameter.DbType = DbType.String;
        parameter.Value = value ? "Y" : "N";
    }
}

// at program start up
SqlMapper.AddTypeHandler(new YnToBoolTypeHandler());

我正在使用 C# 记录类型(即不可变),因此上面使用 Daniel Lorenz 的第二个属性的解决方案对我不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.