C# 如何从数据库中删除指向文件的所有空链接和所有冗余文件

C# 如何从数据库中删除指向文件的所有空链接和所有冗余文件,c#,file,entity-framework-core,C#,File,Entity Framework Core,我正在构建一个可以存储图像的web应用程序。My DB存储指向此映像的路径,所有这些路径都存储在特定目录中。如何从下载文件夹中删除数据库中不存在的所有文件,以及具有空链接的所有数据库记录 例如,我有3个文件:File1.jpg,File2.jpg,File3.jpg。 My DB仅存储File1.jpg和File2.jpg。由于某些原因,File1.jpg已从目录中删除,但其记录仍保留在数据库中。从文件夹中删除File3.jpg(因为它不存储在数据库中)和从数据库中删除File1.jpg(因为它

我正在构建一个可以存储图像的web应用程序。My DB存储指向此映像的路径,所有这些路径都存储在特定目录中。如何从下载文件夹中删除数据库中不存在的所有文件,以及具有空链接的所有数据库记录

例如,我有3个文件:
File1.jpg
File2.jpg
File3.jpg
。 My DB仅存储
File1.jpg
File2.jpg
。由于某些原因,
File1.jpg
已从目录中删除,但其记录仍保留在数据库中。从文件夹中删除
File3.jpg
(因为它不存储在数据库中)和从数据库中删除
File1.jpg
(因为它不存在于文件夹中)的最佳方法是什么

我编写了一个方法来删除未存储在DB中的文件:

    public async Task DeleteNonExistingImagesInFolder(string imagesDirectory)
    {
        var images = _unitOfWork.Images.AsQueryable();
        DirectoryInfo d = new DirectoryInfo(imagesDirectory);
        FileInfo[] Files = d.GetFiles();
        await Task.Run(() =>
        {
            foreach (var file in Files)
            {
                if (!images.Where(i => i.Path == file.FullName).Any())
                    file.Delete();
            }
        });
    }
我对DB记录也做了同样的事情:

    public async Task DeleteNonExistingImagesInDB(string imagesDirectory)
    {
        var images = _unitOfWork.Images.AsQueryable();
        DirectoryInfo d = new DirectoryInfo(imagesDirectory);
        FileInfo[] Files = d.GetFiles();
        await Task.Run(() =>
        {
            foreach (var image in images)
            {
                if (!Files.Where(f => f.FullName == image.Path).Any())
                    _unitOfWork.Images.Remove(image.Id);
            }
        });
    }

但是也许有一种更快的方法。

类似的方法非常有效,只需一小段代码即可完成。这只是检测您想要从2个集合中进行的更改,这是一个有效的示例。请参阅答案的结尾,以获取有关实现需要更改的内容的提示

IEnumerable<string> files = new List<string> { "file1.txt", "file4.txt" };
IEnumerable<string> dbFiles = new List<string> { "file1.txt", "file2.txt", "file3.txt" };

IEnumerable<string> addsToFileSystem = files.Except(dbFiles);
IEnumerable<string> addsToDb = dbFiles.Except(files);

foreach (string file in addsToFileSystem) {
    Console.WriteLine($"delete {file} from file system");
}
foreach (string file in addsToDb) {
    Console.WriteLine($"delete {file} from db");
}
IEnumerable files=新列表{“file1.txt”、“file4.txt”};
IEnumerable dbFiles=新列表{“file1.txt”、“file2.txt”、“file3.txt”};
IEnumerable addsToFileSystem=files.Except(dbFiles);
IEnumerable addsToDb=dbFiles.Except(files);
foreach(addsToFileSystem中的字符串文件){
WriteLine($“从文件系统中删除{file}”);
}
foreach(addsToDb中的字符串文件){
WriteLine($“从数据库中删除{file}”);
}
输出:

从文件系统中删除file4.txt

从数据库中删除file2.txt

从数据库中删除file3.txt

//从“我的文件”目录获取文件集合,并仅选择文件名
IEnumerable files=目录。枚举文件(“我的文件”)。选择(x=>Path.GetFileName(x))
//替换为从数据库中选择文件名
IEnumerable dbFiles=_unitOfWork.Images.Select(x=>x..FileName);
IEnumerable addsToFileSystem=files.Except(dbFiles);
IEnumerable addsToDb=dbFiles.Except(files);
foreach(addsToFileSystem中的字符串文件){
//从文件系统中删除
}
foreach(addsToDb中的字符串文件){
//从数据库中删除
}
“最佳方式”非常主观,取决于基础架构的其他部分。你具体试过什么?是的,处理这个问题真的没有“最好”的方法。毫无疑问,当您在查询中获取一个文件时,我会进行检查以确保该文件确实存在。如果没有,请将其从表中删除。如果您只是在例外情况下这样做,并正确地锁定文件系统,这样就不会发生类似的事情,那就更好了。@mxismool,“最好的方法”我的意思是用更少的代码和尽可能快的速度。
// get collection of files from "my files" directory and select just the file name
IEnumerable<string> files = Directory.EnumerateFiles("my files").Select(x => Path.GetFileName(x))
// replace with selecting the file names from your database
IEnumerable<string> dbFiles = _unitOfWork.Images.Select(x => x..FileName);

IEnumerable<string> addsToFileSystem = files.Except(dbFiles);
IEnumerable<string> addsToDb = dbFiles.Except(files);

foreach (string file in addsToFileSystem) {
    // remove from file system
}
foreach (string file in addsToDb) {
    // remove from db
}