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 内有 0 个外键 (BID) 的块,我想删除该块。

因此,基本上,如果 Blocks 中存在 BID 而 ModuleBlock 中不存在,我想删除该 Block。

并删除每个带有 FK(BID) 的 BlockLanguage,即要删除的块的 PK(BID)。

这必须通过数据上下文上的一个submitChanges 来实现。我已经为此工作了一个小时,但我只是缺乏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

因此,基本上,如果 Blocks 中存在 BID 而 ModuleBlock 中不存在,我想删除该 Block。

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

并删除每个带有 FK(BID) 的 BlockLanguage,即要删除的块的 PK(BID)

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

这必须发生在数据上下文上的 ONE submitChanges

Block您可以使用以下方法一次性删除实体集合:

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

db.SubmitChanges();
于 2012-08-17T12:50:58.893 回答
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 的替代逻辑。它会删除所有没有现有 Block 的 BlockLanguages,无论 Block 是否刚刚被删除。优点是它只依赖于剩余的BlockIds。

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