2

データベースに追加する前に現在のアイテムがデータベースに存在するかどうかを確認する方法があります。存在する場合はアイテムを削除し、そうでない場合は追加します。

これを行うより良い方法はありますか?今のところ、タイトルはまったく同じでなければならないからです。タイトルに文字/単語の違いがある場合、それは削除されません。

基本的に私が意味するのはこれです:

タイトルが「ロナウドは右足を失った」で、データベースに「ロナウドは昨日右足を失った」というタイトルがある場合、現在のアイテムを削除する必要があります。

もう一つの例:

タイトルが「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

あなたの質問は、明確な答えを提供するよう促すよりも多くの質問を提起します。AddItemというメソッドで項目を削除したい理由をお聞きしてもよろしいですか? アイテムの識別子が引数として提供されたものと一致する場合、アイテムを更新したいということではありませんか?

そうは言っても、目的の動作を実装するには基本的に 2 つのオプションがあります。コードで一致を実行するか、データベースで一致を実行します。ただし、当然のことながら、どちらも 2 人が 2 人が一致することを意味するものを正確に定義する必要があります。他の答えはすでにそれを示唆しています。

コードで一致を実行する利点は柔軟性です。一般に、この種の (複雑な) ロジックは、SQL で記述するよりも C# でプログラミングする方が簡単です。さらに、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);

したがって、一致しない単語については、レーベンシュタイン距離を使用して単語比較ごとにスコアを取得できます。以下のコードを含めましたが、これが正しく機能する実装であるかどうかをテストしていません。とにかく、これを使用する理由は、ある単語を別の単語に一致させるために必要な操作の数によって、各単語を比較できるからです。そのため、非常に近いスペルミスの単語は同じと見なすことができます。

ただし、指摘されているように、プロセス全体で非常にエラーが発生しやすくなります。あなたが本当にやりたいことは、2 つの文字列の意味を比較することです。私たちはその方向に進んでいますが、文から意味を解析するためのカウンター AI を介した 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

于 2013-07-22T19:01:58.170 に答える
0

データベースに追加する前に現在のアイテムがデータベースに存在するかどうかを確認する方法があります。存在する場合はアイテムを削除し、そうでない場合は追加します。

アイテムが見つかったら削除(および再度追加) しますか? おそらく、代わりにデータを更新する方法を見つけたいと思うでしょう。これにより、はるかに効率的になり、エラーが発生しにくくなります。(たとえば、delete を使用すると、数ミリ秒間すべてのユーザーのレコードが失われ、クライアントが間違った時間にクラッシュした場合、レコードは永久に失われます。)

また、ユーザーが入力したすべての内容を記録することもできます。

1) 後で「人々が検索したもの」を「人々が本当に欲しかったもの」にマッピングするのに役立ちます。1 人がタイプミスすると、他の人も同じようにタイプミスする可能性があります。(つまり、"the" と入力するときに "tqe" と入力することはめったにありません。しかし、彼らは常に "teh" と入力します。)

2)どれが「最高」かはわかりません。より多くの言葉が常に良いとは限りません。

複数の名前を項目属性を持つ項目テーブル内の同じ項目にマップできるようにする「name, item_id」を持つ名前テーブルを持つ方がおそらく良いでしょう。

于 2013-07-25T04:10:10.997 に答える