public static IReadOnlyList <File> AddFilesToClass(UpdateFilesArgs args) { Debug.WriteLine("db begin: " + nameof(AddFilesToClass)); List <File> fs = new List <File>(); if (args.Files.Any(p => !p.StartsWith(args.Project.RootPath))) { throw new Exception("文件不在项目目录下"); } int index = 0; int count = args.Files.Count; DateTime lastCallbackTime = DateTime.MinValue; foreach (var path in args.Files) { File f = new File(new FI(path), args.Project); File existedFile = db.Files.FirstOrDefault(p => p.Name == f.Name && p.Dir == f.Dir); //文件不存在的话,需要首先新增文件 if (existedFile == null) { args.GenerateThumbnailsMethod?.Invoke(f); //if (args.IncludeThumbnails) //{ // FileUtility.TryGenerateThumbnail(f); //} //if (args.IncludeExplorerIcons) //{ // FileUtility.TryGenerateExplorerIcon(f); //} db.Files.Add(f); } else { var existedFileClass = db.FileClasses.FirstOrDefault(p => p.Class == args.Class && p.File == existedFile); //如果文件已存在,就搜索一下是否存在关系,存在关系就不需要继续了 if (existedFileClass != null && existedFileClass.Status != FileClassStatus.Disabled) { goto next; } //存在但被禁用 if (existedFileClass != null && existedFileClass.Status == FileClassStatus.Disabled) { fs.Add(existedFile); existedFileClass.Status = FileClassStatus.Auto; db.Entry(existedFileClass).State = EntityState.Modified; goto next; } f = existedFile; } db.FileClasses.Add(new FileClass(args.Class, f, true)); fs.Add(f); next: index++; if (args.Callback != null && (DateTime.Now - lastCallbackTime).TotalMilliseconds > CallbackUpdateMs) { lastCallbackTime = DateTime.Now; if (!args.Callback(index * 1.0 / count, f)) { db.SaveChanges(); return(null); } } } SaveChanges(); Debug.WriteLine("db end: " + nameof(AddFilesToClass)); return(fs.AsReadOnly()); }
public static void UpdateFilesOfClasses(UpdateFilesArgs args) { Debug.WriteLine("db begin: " + nameof(UpdateFilesOfClasses)); //dbFiles只在需要刷新物理文件时用到,但是因为有两个作用域,所以写在了外层 HashSet <File> dbFiles = null;//= new HashSet<File>(Queryable.Where(DbUtility.db.Files, (System.Linq.Expressions.Expression<Func<File, bool>>)(p => (bool)(p.Project == args.Project)))); List <File> files = null; if (args.Research) { dbFiles = new HashSet <File>(db.Files.Where(p => p.ProjectID == args.Project.ID)); IReadOnlyList <System.IO.FileSystemInfo> diskFiles = FzLib.IO.FileSystem.EnumerateAccessibleFileSystemInfos(args.Project.RootPath); if (args.DeleteNonExistentItems) { HashSet <string> paths = new HashSet <string>(diskFiles.Select(p => p.FullName)); //删除已不存在的文件 foreach (var file in dbFiles) { if (!paths.Contains(file.GetAbsolutePath())) { db.Entry(file).State = EntityState.Deleted; } } db.SaveChanges(); } files = diskFiles .OfType <FI>() .Select(p => new File(p, args.Project)).ToList(); } else { files = db.Files.Where(p => p.ProjectID == args.Project.ID).Include(p => p.Project).ToList(); } //现在数据库中该项目的所有文件应该都存在相对应的物理文件 int index = 0; int count = files.Count; DateTime lastCallbackTime = DateTime.MinValue; var classes = db.Classes.ToList(); foreach (var file in files) { File f = null;// new File(file, args.Project); if (args.Research) { //先判断一下数据库中是否已存在该文件 if (!dbFiles.Contains(file)) { f = file; db.Files.Add(f); } else { //如果数据库中存在该文件,则从HashSet中提取该文件 if (!dbFiles.TryGetValue(file, out File newF)) { //理论上不会进来 Debug.Assert(false); } f = newF; } args.GenerateThumbnailsMethod?.Invoke(f); //if (args.IncludeThumbnails) //{ // FileUtility.TryGenerateThumbnail(f); //} //if (args.IncludeExplorerIcons) //{ // FileUtility.TryGenerateExplorerIcon(f); //} } else { f = file; } if (args.Reclassify) { foreach (var c in classes.Where(p => p.ProjectID == args.Project.ID)) { FileClass fc = IncludeAll(db.FileClasses) .FirstOrDefault(p => p.Class == c && p.File == f); bool isMatched = FileUtility.IsMatched(f.FileInfo, c); if (fc == null && isMatched) { //如果匹配并且不存在,那么新增关系 db.Add(new FileClass(c, f, false)); } else if (fc != null && !isMatched && fc.Status != FileClassStatus.AddManully) { //如果存在关系但不匹配,那么应该删除已存在的关系 //注意,手动删除的关系并不会走到这一步 db.Entry(fc).State = EntityState.Deleted; } //其他情况,既不需要增加,也不需要删除 } } index++; if (args.Callback != null && (DateTime.Now - lastCallbackTime).TotalMilliseconds > CallbackUpdateMs) { lastCallbackTime = DateTime.Now; if (!args.Callback(index * 1.0 / count, f)) { db.SaveChanges(); return; } } } db.SaveChanges(); Debug.WriteLine("db end: " + nameof(UpdateFilesOfClasses)); }