2

このようなコードのような私の問題解決;

    string permalink = "computers/hp/computers"; //example for similarity
    List<string> aliases = permalink.Split('/').ToList();

    Category cat = db.Categories.SingleOrDefault(c => c.Alias == aliases.First());
    aliases.Remove(aliases.First());

    foreach (string alias in aliases)
    {
        cat = cat.Categories.SingleOrDefault(c => c.Alias == alias);
    }

    return cat;

しかし、これは多くのクエリが送信されます..

1回どうやって作るの?

4

3 に答える 3

0

私はおそらくあなたの混乱に追加するだけです:)、しかし、私はただアイデアを投げさせてください...これは機能しない
とだけ言っておきましょう(正確にあなたの仕様に従って)-そしてそれは解決策ではありませんが、あなたを簡素化するのに役立つかもしれません物事は少し。

var query = 
    (from cat in db.Categories
     where cat.Alias == "mainAalias"
     from subcat in cat.Categories
     where aliases.Contains(subcat.Alias)
     orderby subcat.Alias descending
     select subcat);  
query.FirstOrDefault(); // or something

これにより、1 つの比較的単純なクエリが生成されます
(例: SELECT...FROM...JOIN...WHERE... AND...IN...ORDERBY...)。

たとえば、'cat1', 'cat2'...'cat6' - cat1 から - cat100 へ - 'cat6'...'cat1' を与える場合 (別名)

ただし、「並べ替え」には大きな「欠陥」があります。仕様では、「エイリアス」の順序である並べ替えが必要as they comeです。これは、クエリにとっては少し残念です。SQLに変換できる順序を何らかの方法で強制または定義できれば、これ(または同様のもの)が機能する可能性があります。

このクエリが機能するためには、「エイリアス」が昇順で事前にソートされていると想定しています。それらはそうではありません、そして私はそれを知っています。

しかし、あなたのアイデアはここでは明確に定義されていないと思います (そして、なぜ私たち全員が問題を抱えているのか) - よく考えて最適化し、要件を簡素化し、C# 層を事前ソートなどで支援させてください。

cat.Alias などごとに何らかの形式の「グループ化」を試すこともできますが、同じ「ソートの問題」が続くと思います。

于 2013-04-04T01:40:36.127 に答える
0

まず、カテゴリ テーブルが小さい場合は、テーブル全体を取得してメモリ内で選択する方がよい場合があります (おそらく pwsg の回答を使用します)。

テーブルが大きい場合は、Linq よりもストアド プロシージャの方が適している可能性があります。

しかし、本当にLinqでやりたいのなら、同じテーブルに結合を繰り返し追加するしか方法はないと思います。

以下は、あなたの関係が ParentID と Id と呼ばれるフィールドの間であると仮定しています。また、順序をわかりやすくするために、文字列のパーマリンクも変更しました。

最初に小さなヘルパー クラスが必要です

public class Info
{
    public Category category;
    public int? recordID;
}

次に、メインコード

string permalink ="computers1/hp/computers2"; 
var aliases = permalink.Split('/');

var query = dc.Categories.Where(r=>r.Alias == aliases[aliases.Length-1])
              .Select(r=> new Info { category = r,  recordID = r.ParentID});

    for(int i = aliases.Length -2 ; i >= 0; i--)
    {
        string alias = aliases[i]; 
        query =  query.Join(dc.Categories , 
                            a => a.recordID , b => b.Id , (a,b) => new { a , b} )
        .Where(r=>r.b.Alias == alias)
        .Select(r=> new Info { category = r.a.category, recordID = r.b.ParentID});
    }

    return query.SingleOrDefault().category;

ご覧のとおり、結合のラムダ構文は (IMHO) 恐ろしく、私は通常それを回避しようとしますが、とにかくここでそれを回避することは考えられません。

私はそれをテストできないので、完全に間違っている可能性があります (ID、ParentID、または a と b を混同した可能性があります)。そのため、これをテストし、そのパフォーマンスをテストすることが重要です。

生成されたSQLは次のようになるはずだと思います

SELECT * from Categories AS t0
INNER JOIN Categories AS t1 ON t0.ParentID = t1.id
INNER JOIN Categories AS t2 ON t1.ParentID = t2.id
WHERE t2.Alias = 'computers1' 
  AND t1.Alias = 'hp' 
  AND t0.Alias = 'computers2'

セクションまたはエイリアスが多いほど、結合が多くなります。

すべてを確認したので、おそらくこのメソッドの使用を避けたいと思うでしょう -)

于 2013-04-03T22:18:26.270 に答える