2

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

有没有更好的方法来做到这一点?因为现在标题必须完全相同。如果标题有字符/单词差异,则不会删除它。

基本上我的意思是这样的:

如果标题是“C罗失去了右腿”并且数据库中有一个标题是“C罗昨天失去了右腿”,它应该删除当前项目。

另一个例子:

如果标题是“hello world”并且数据库中有一个标题是“hello world everyone”,它应该删除当前项目。

所以基本上如果文本有常用词,它应该删除该项目。

这是我到目前为止的方法:

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

任何形式的帮助表示赞赏。

4

5 回答 5

0

我不知道 C#,但 BASIC 有 instr$,而 javascript 有 indexOf()... C# 可能有类似的东西,它会检查你的字符串是否存在于另一个字符串中——这意味着它将显示为“hello”的匹配项" 或 "hello world" 或 "world hello" 如果你搜索 "hello",但 "hello world" 不会找到 "world hello"...因为我不知道 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);
}

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

于 2013-07-21T13:41:33.887 回答
0

您的问题提出的问题多于提供明确答案的问题。我可以问一下您为什么要删除名为AddItem的方法中的项目吗?您不是说要在其标识符与作为参数提供的标识符匹配时更新一个项目吗?

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

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

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

于 2013-07-22T13:29:03.557 回答
0

首先,我同意@Jonesy 的观点,字符串可以使用

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

null 强制在空格上分裂。请参阅:在 String.Split 操作中指定空格的最佳方法

这些词可以放入列表中。列表的交集会立即告诉您哪些单词完全匹配,以及有多少单词完全匹配。任何其他单词都是不匹配的单词。

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

所以对于不匹配的单词,你可以使用 Levenshtein 距离为每个单词比较得到一个分数。我在下面包含了代码,但尚未测试这是否是正确工作的实现。无论如何,使用它的原因是您可以通过使一个单词匹配另一个单词需要多少操作来比较每个单词。因此,非常接近的拼写错误的单词可以被视为相等。

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

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

于 2013-07-22T19:01:58.170 回答
0

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

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

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

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

2)你永远不知道哪个是“最好的”。更多的词并不总是更好。

您最好有一个带有“name, item_id”的名称表,它允许多个名称映射到具有项目属性的项目表中的同一个项目。

于 2013-07-25T04:10:10.997 回答
-1

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

在两端使用 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(), ""));

和“Hello world”将匹配“Hello World!”

于 2013-07-16T20:23:43.987 回答