我如何改进一种方法来检查数据库中是否已经存在当前项

本文关键字:是否 数据库 存在 检查 何改进 方法 一种 | 更新日期: 2023-09-27 18:22:33

我有一个方法,在将当前项添加到数据库之前,它会检查数据库中是否存在该项,如果它确实存在,它会删除该项,否则它会添加该项。

有更好的方法吗?因为现在的标题必须完全相同。如果标题有字符/单词差异,那么它不会删除它。

基本上我的意思是:

如果标题是"罗纳尔多失去了右腿",并且数据库中有一个标题是"昨天罗纳尔多失去了左腿",则应删除当前项目。

另一个例子:

如果标题是"helloworld",并且数据库中有一个标题是"Helloworldeveryone",则应该删除当前项。

因此,基本上,如果文本中有常用词,就应该删除该项。

这是我迄今为止的方法:

public void AddNews(News news)
    {
        var exists = db.News.Any(x => x.Title == news.Title);
         if (exists == false)
        {
            db.News.AddObject(news);
        }
        else
        {
            db.News.DeleteObject(news);
        }
    }

任何形式的帮助都将不胜感激。

我如何改进一种方法来检查数据库中是否已经存在当前项

首先,我同意@Jonesy的观点,即使用可以将字符串拆分为单词

string[] list1 = myStr.Split(null);

null强制在空白处进行拆分。请参阅:在字符串中指定空白的最佳方法。拆分操作

并且这些单词可以被放入列表中。列表的交集立刻告诉你哪些单词匹配得很好,有多少单词匹配得非常好。任何其他单词都是不匹配的单词。

var result = list1.Intersect(list2, StringComparer.InvariantCultureIgnoreCase);

因此,对于不匹配的单词,可以使用Levenstein距离为每个单词的比较打分。我在下面包含了代码,但还没有测试这是否是一个正常工作的实现。无论如何,使用这个的原因是,你可以通过使一个单词与另一个单词匹配所需的操作次数来比较每个单词。因此,拼写错误的单词非常接近可以算作相等。

然而,正如已经指出的那样,整个过程将非常容易出错。听起来你真正想做的是比较这两个字符串的含义,虽然我们在这个方向上取得了进展,但我还不知道有任何C#可以从句子中解析含义。

using System;
/// <summary>
/// Contains approximate string matching
/// </summary>
static class LevenshteinDistance
{
    /// <summary>
    /// Compute the distance between two strings.
    /// </summary>
    public static int Compute(string s, string t)
    {
    int n = s.Length;
    int m = t.Length;
    int[,] d = new int[n + 1, m + 1];
    // Step 1
    if (n == 0)
    {
        return m;
    }
    if (m == 0)
    {
        return n;
    }
    // Step 2
    for (int i = 0; i <= n; d[i, 0] = i++)
    {
    }
    for (int j = 0; j <= m; d[0, j] = j++)
    {
    }
    // Step 3
    for (int i = 1; i <= n; i++)
    {
        //Step 4
        for (int j = 1; j <= m; j++)
        {
        // Step 5
        int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
        // Step 6
        d[i, j] = Math.Min(
            Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
            d[i - 1, j - 1] + cost);
        }
    }
    // Step 7
    return d[n, m];
    }
}

此处引用:http://www.dotnetperls.com/levenshtein

我不知道C#,但BASIC有instr$,javascript有indexOf()。。。C#可能有类似的东西,它会检查你的字符串是否存在于另一个字符串中——这意味着如果你搜索"你好",它将显示为"你好"、"你好世界"或"世界你好"的匹配,但"你好世界"找不到"世界你好。。。由于我不知道C#,这不是有效的代码,但应该会让你走上正轨。。。

var dbTitle = wherever you get the existing titles from
var yourSearchTerm = what you want to find
if (dbTitle.indexOf(yourSearchTerm)>0) { //indexOf() returns -1 if match not found
db.News.AddObject(news);
}
else {
db.News.DeleteObject(news);
}

在帮助文件中搜索字符串操作以找到正确的命令。

您的问题提出的问题比提供明确答案所邀请的问题更多。请问您为什么要在名为AddItem的方法中删除项?当项目的标识符与作为参数提供的标识符匹配时,您不是想更新吗?

话虽如此,实现所需行为基本上有两种选择:在代码中执行匹配,或在数据库中执行匹配然而,两者自然都需要你们两个确切地定义什么是两个匹配。其他答案已经暗示了这一点。

在代码中执行匹配的优点是灵活性:在C#中对这种(复杂的)逻辑进行pogram通常比在SQL中编写更容易。此外,您将免费获得持久性代码,因为您可以使用EF(我假设您正在使用代码示例)。

在SQL中执行此操作的优点是性能更高,因为在做出插入/更新/删除决定之前,不必从数据库中检索整个实体。您可以通过在实体表上添加INSTEAD-OF INSERT触发器来实现这一点,并在发现所提供的实体实际上与现有实体匹配时执行更新/删除。

我有一个方法,在将当前项目添加到数据库之前,检查该项目是否存在于数据库中,如果它确实存在,则删除该项目,否则添加该项目。

您确定要在找到项目时删除(并重新添加?)吗?您可能想找到一种更新数据的方法。这样会更有效率,也不容易出错。(例如,如果你使用delete,你的记录将在几毫秒内丢失,如果客户端在错误的时间崩溃,它将永远消失。)

此外,您可能希望记录用户键入的所有内容。

1) 它们有助于以后将"人们搜索的内容"映射为"人们真正想要的内容"。如果一个人打字错误,很可能其他人也会用同样的方式打字。(即人们在键入"the"时很少键入"tqe"。但他们总是键入"teh"。)

2) 你永远不知道哪一个是"最好的"。多说话并不总是更好。

您最好拥有一个带有"name,item_id"的名称表,它允许多个名称映射到具有item属性的items表中的同一个item。

如果标题只是有一个小的字符差异,它不会删除它。

在两端使用ToUpper()将确保有效的检查,即使外壳是不同的

var exists = db.News.Any(x => x.Title.ToUpper() == news.Title.ToUpper());

如果您想要其他方法来检查对象是否存在,我们需要更多信息。

更新

在你的评论中,你可以从中删除所有非字母数字字符

Regex rgx = new Regex("[^a-zA-Z0-9 -]");
var exists = db.News.Any(x => rgx.Replace(x.Title.ToUpper(), "") == rgx.Replace(news.Title.ToUpper(), ""));

"你好世界"将与"你好世界!"

匹配