Reputation: 3030
Let's say I have the following classes in 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
}
Now, I'd like to delete a set of moduleBlocks
var toBeDeletedModuleBlocks = // Query, select ModuleBlocks to be deleted
The query for toBeDeletedModuleBlocks is could be arbitrary, as long as it selects ModuleBlocks.
For each Block that has will have 0 of its foreign keys (BID) inside ModuleBlock AFTER ModuleBlocks have been deleted, I'd like to delete that Block.
So basically if there exists a BID in Blocks that does not exist in ModuleBlock, I'd like to delete that Block.
And delete every BlockLanguage with the FK(BID) that is the PK(BID) of the Blocks that are to be deleted.
And this has to happen with one submitChanges on the datacontext. I've been working on this for an hour, but I simply lack the LINQ knowledge to query everything I need to delete.
In the end I'd like to be able to do this:
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()
}
Now I'd like to compare allBlocksCount & theseBlockscount, if Count equals each other that means that there will be 0 references left in BlockString, so I'd like a query that gives me all the Blocks (BIDs) where count in allBlocksCount && theseBlocksCount is equal.
But I don't know enough LINQ to make that query. If I knew how to do that query I could fill toBeDeletedBlocks and toBeDeletedBlockLanguages
And then I could do this.
Context.ModuleBlocks.DeleteAllOnSubmit(toBeDeletedModuleBlocks);
Context.Blocks.DeleteAllOnSubmit(toBeDeletedBlocks);
Context.BlockLanguages.DeleteAllOnSubmit(toBeDeletedBlockLanguages);
Context.SubmitChanges();
Upvotes: 1
Views: 1927
Reputation: 2521
I'm not sure if this will work, but this is the logic that you want, right?
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
This is alternate logic for deleting BlockLanguages. It deletes all BlockLanguages that don't have an existing Block, regardless of if the Block was just deleted. The advantage is it is only dependent on remainingBlockIds.
var toBeDeletedBlockLanguages = context.BlockLanguages.Where(bl => remainingBlockIds.Contains(bl.BID) == false);
Upvotes: 1
Reputation: 172646
So basically if there exists a BID in Blocks that does not exist in ModuleBlock, I'd like to delete that Block.
var blocksWithoutModules =
from block in db.Blocks
where !db.ModuleBlocks.Any(m => m.Block == block)
select block;
And delete every BlockLanguage with the FK(BID) that is the PK(BID) of the Blocks that are to be delted
var languagesToDelete =
from block in blocksWithoutModules
select block.Language;
And this has to happen with ONE submitChanges on the datacontex
You can delete the collection of Block
entities in one go using:
db.Blocks.DeleteAllOnSubmit(blocksWithoutModules);
db.Languages.DeleteAllOnSubmit(languagesToDelete);
db.SubmitChanges();
Upvotes: 1