1

LINQ to SQLに次のクラスがあるとします。

Module
{
    long MID    // PK
    string Name
}

ModuleBlock
{
    long MID      // FK
    long BID      // FK
}

Block
{
    long BID      // PK
    string Info
}

BlockLanguage
{
    long BID      // FK
    long LID      // FK
}

Language
{
    long LID      // FK
    string Language
}

ここで、一連の moduleBlocks を削除したいと思います

var toBeDeletedModuleBlocks = // Query, select ModuleBlocks to be deleted

toBeDeletedModuleBlocks のクエリは、ModuleBlocks を選択する限り、任意である可能性があります。

ModuleBlocks が削除された後、ModuleBlock 内の外部キー (BID) が 0 になるブロックごとに、そのブロックを削除したいと思います。

基本的に ModuleBlock に存在しない BID が Blocks に存在する場合、その Block を削除したいと考えています。

そして、削除するブロックの PK(BID) である FK(BID) を持つすべての BlockLanguage を削除します。

これは、 datacontext の1 つのsubmitChanges で発生する必要があります。私はこれに 1 時間取り組んできましたが、削除する必要があるすべてのものをクエリするためのLINQの知識が不足しているだけです。

最後に、私はこれを行うことができるようにしたいと思います:

var toBeDeletedModuleBlocks =
    from moduleBlocks in context.ModuleBlocks
    where block.MID == 5 // assume block with MID = 5 exists
    select moduleBlocks

// Count of each block referenced by ModuleStrings
var allBlocksCount = 
   from moduleBlock in context.ModuleBlocks
   join block in context.Blocks on ModuleBlock.bID equals block.Bid
   group by block by block.BID into counter
   select new
   {
      BID = counter.Key,
      Count = counter.Count()
   };

// Count of each block that is going to be deleted, in this case it has a maximum of 1 (one module in each where).
var theseBlocksCount =
   from moduleBlock in context.ModuleBlocks
   join block in context.Blocks on ModuleBlock.bID equals block.Bid
   where moduleStrings.MID == 5 // 5 again, these are going to be deleted
   groub by 
   select new
   {
      BID = count.Key
      Count = counter.Count()
   }

ここで、allBlocksCount と theseBlockscount を比較したいと思います。Count が互いに等しい場合、つまり、BlockString に残っている参照が 0 になることを意味します。そのため、allBlocksCount && theseBlocksCount でカウントされるすべてのブロック (BID) を取得するクエリが必要です。等しいです。

しかし、そのクエリを作成するのに十分な LINQ を知りません。そのクエリの実行方法を知っていれば、 toBeDeletedBlockstoBeDeletedBlockLanguagesを入力できます。

そして、私はこれを行うことができました。

Context.ModuleBlocks.DeleteAllOnSubmit(toBeDeletedModuleBlocks);
Context.Blocks.DeleteAllOnSubmit(toBeDeletedBlocks);
Context.BlockLanguages.DeleteAllOnSubmit(toBeDeletedBlockLanguages);
Context.SubmitChanges();
4

2 に答える 2

1

これが機能するかどうかはわかりませんが、これはあなたが望むロジックですよね?

var remainingBlockIds = context.ModuleBlocks.Except(toBeDeletedModuleBlocks)
                                            .Select(mb => mb.BID)
                                            .Distinct();
var toBeDeletedBlocks = context.Blocks.Where(b => remainingBlockIds.Contains(b.BID) == false);
var toBeDeletedBlockIds = toBeDeletedBlocks.Select(b => b.BID);
var toBeDeletedBlockLanguages = context.BlockLanguages.Where(bl => toBeDeletedBlockIds.Contains(bl.BID));
// Then delete toBeDeletedModuleBlocks, toBeDeletedBlocks, and toBeDeletedBlockLanguages 

これは、BlockLanguagesを削除するための代替ロジックです。ブロックが削除されたかどうかに関係なく、既存のブロックがないすべてのBlockLanguagesが削除されます。利点は、remainingBlockIdsのみに依存することです。

var toBeDeletedBlockLanguages = context.BlockLanguages.Where(bl => remainingBlockIds.Contains(bl.BID) == false);
于 2012-08-17T14:02:59.057 に答える
1

基本的に ModuleBlock に存在しない BID が Blocks に存在する場合、その Block を削除したいと考えています。

var blocksWithoutModules =
    from block in db.Blocks
    where !db.ModuleBlocks.Any(m => m.Block == block)
    select block;

そして、削除するブロックの PK(BID) である FK(BID) を持つすべての BlockLanguage を削除します。

var languagesToDelete =
    from block in blocksWithoutModules
    select block.Language;

そして、これはdatacontexの1つのsubmitChangesで発生する必要があります

Block次を使用して、エンティティのコレクションを一度に削除できます。

db.Blocks.DeleteAllOnSubmit(blocksWithoutModules);
db.Languages.DeleteAllOnSubmit(languagesToDelete);

db.SubmitChanges();
于 2012-08-17T12:50:58.893 に答える