【问题标题】:How to check if statements dynamically如何动态检查 if 语句
【发布时间】:2018-08-02 03:31:40
【问题描述】:

我的问题如下,我需要通过数据库检查条件。这意味着在简单的应用程序中,我们检查是否有这样的条件。

private static void Main(string[] args)
{
    Console.WriteLine("Enter your age");
    var age = int.Parse(Console.ReadLine() ?? throw new InvalidOperationException());

    if (5 <= age && age <= 10)
    {
        Console.WriteLine("Range 5 - 10");
    }else if (11 <= age && age <= 20)
    {
        Console.WriteLine("Range 11 - 20");
    }
    else if (21 <= age && age <= 30)
    {
        Console.WriteLine("Range 21 - 30");
    }
    else
    {
        Console.WriteLine("Over range");
    }
}

假设客户需要动态更改条件,这意味着他需要向系统添加额外的条件,例如,

if 31 &lt;= age &amp;&amp; age &lt;= 40 => 范围 31 - 40

在客户端执行此操作时,有时会向系统添加错误条件,例如,

(4 &lt;= age &amp;&amp; age &lt;= 15)这个条件不能加,因为系统已经有条件(5 &lt;= age &amp;&amp; age &lt;= 10)。当年龄为 7 岁时,这两个条件都将成立。像这种情况下,最好的办法是什么。

我需要将条件存储在我的数据库中,(PS:数据库表结构可以根据你的回答改变)

作为示例表结构

ConditionID    Condition                  Details

con001         5 <= age && age <= 10      Range 5 - 10
con002         11 <= age && age <= 20     Range 11 - 20
con003         21 <= age && age <= 30     Range 21 - 30

请给我一个解决方案来解决这个问题。我如何使用 C# 和 oracle SQL 来做到这一点

【问题讨论】:

  • 你想在哪里处理这个代码端或数据库端?
  • @DipteeHamdapurkar 双方都可以,但我认为代码方面最好。但是如果可以的话,数据库方面也很好
  • 您正在构建一个规则引擎。您可能认为这不是您正在做的事情,但如果您想要一个例程来验证动态创建的条件,那么您就开始了这一旅程。因此,这将是检查这是否是您想要做的事情的好点,如果是,您是否会更好地使用现有的规则引擎而不是从头开始滚动自己的引擎。
  • @APC 你能提供一个示例代码吗

标签: c# sql .net if-statement


【解决方案1】:

首先,您不需要将Details 存储为列,因为您可以稍后在代码中以动态方式构建它。其次,您也不需要将 Condition 存储为字符串列,因为当您想将其解析为 C# 代码中的条件时,它会使您的工作更加复杂。您只需要在数据库中存储两个整数值作为LowerUpper 范围的值,并生成ConditionID 标识。你的表格应该是这样的:

CREATE TABLE [dbo].[tblConditions] (
[ConditionID] INT IDENTITY (1, 1) NOT NULL,
[Lower]       INT NOT NULL,
[Upper]       INT NOT NULL,
PRIMARY KEY CLUSTERED ([ConditionID] ASC)
);

然后你可以在你的代码中写这样的东西:

Console.WriteLine(@"Enter your age");
var age = int.Parse(Console.ReadLine() ?? throw new InvalidOperationException());

using (var db = new forTestEntities())
{
    var result = db.tblConditions.Where(c => c.Lower <= age && age <= c.Upper).AsEnumerable()
        .Select(c => $"Range {c.Lower} - {c.Upper}")
        .DefaultIfEmpty("Over range").SingleOrDefault();

    Console.WriteLine(result);
}

编辑:如果您不熟悉这个$ 运算符,它被称为String Interpolation,它在C# 6+ 中可用,如果您使用的是旧版本的C#,您可以像这样使用string.Format

c => string.Format("Range {0} - {1}", c.Lower, c.Upper)

还可以使用以下代码向数据库添加动态条件:

Console.WriteLine(@"Enter Lower");
var lower = int.Parse(Console.ReadLine() ?? throw new InvalidOperationException());

Console.WriteLine(@"Enter Upper");
var upper = int.Parse(Console.ReadLine() ?? throw new InvalidOperationException());

using (var db = new forTestEntities())
{
    var newCondition = new tblCondition
    {
        Lower = lower,
        Upper = upper
    };

    var range = Enumerable.Range(newCondition.Lower, 
                            newCondition.Upper - newCondition.Lower + 1);

    var check = db.tblConditions.AsEnumerable().Any(c => range
                .Intersect(Enumerable.Range(c.Lower, c.Upper - c.Lower + 1)).Any());

    if (!check)
    {
        db.tblConditions.Add(newCondition);
        db.SaveChanges();
    }
}

请注意:我使用的是 SQL Server 和 Entity Framework-DB First 方法,您可以根据需要进行更改。

【讨论】:

  • 非常感谢。我还没有尝试过。你能告诉我,当表包含Lower = 5 &amp; Upper = 10 时,用户不能将此值包含到数据库中,例如Lower = 3 &amp; Upper = 12,因为例如当年龄 = 8 时,这两个条件都将通过。我可以使用您的代码防止这种情况发生吗?
  • @Sachith 不客气。我已经对此进行了检查,并且也包括了该验证。检查此行:var range = Enumerable.Range(newCondition.Lower, newCondition.Upper - newCondition.Lower + 1); var check = db.tblConditions.AsEnumerable().Any(c =&gt; range .Intersect(Enumerable.Range(c.Lower, c.Upper - c.Lower + 1)).Any());
  • @Sachith 我使用Intersect 进行此类验证。
  • 代码运行良好。谢谢,兄弟:) 我在这里你用的是VS2017?我使用VS2013对此进行了测试。在 VS2013 .Select(c =&gt; $"Range {c.Lower} - {c.Upper}") 中使用此代码时,此行会出错。问题是 $。所以我删除了它。但删除后输出显示为Range {c.Lower} - {c.Upper}。如何避免这种情况。我可以在 Oracle 中执行此操作吗?希望它没有出错:) 再次感谢
  • 谢谢您,先生,非常感谢您的回复和努力
【解决方案2】:

您只需存储一个数字列表即可完成这项工作。试试这样的:

var ages = new [] { 5, 10, 20, 30 };

var limits = ages.Zip(ages.Skip(1), (a0, a1) => new
{
    lower = a0,
    upper = a1,
    message = $"Range {a0} - {a1}"
});

var age = int.Parse(Console.ReadLine());
var message =
    limits
        .Where(l => l.lower <= age && l.upper >= age)
        .Select(l => l.message)
        .DefaultIfEmpty("Over range")
        .First();

Console.WriteLine(message);

如果我运行它并输入25,则会出现消息"Range 20 - 25"

【讨论】:

    猜你喜欢
    • 2014-12-27
    • 2016-01-29
    • 2019-08-20
    • 1970-01-01
    • 2011-01-03
    • 2015-03-13
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多