Prevent EFModelFileManager.ttinclude from deleting previously generated code by other model
Sancho-Lee opened this issue · 0 comments
Sancho-Lee commented
EFDesigner v4.2.1.3
Phenomenon:
If there are more than one model in a project, files created in other models are deleted when code is generated for a specific model.
In EFModelFileManager.ttinclude,
private void ProjectSync(IEnumerable<string> keepFileNames)
{
Dictionary<ProjectItem, List<string>> current = GetCurrentState();
string[] fileNames = keepFileNames as string[] ?? keepFileNames.ToArray();
Dictionary<ProjectItem, List<string>> target = GetTargetState(fileNames);
List<string> allTargetFiles = target.Keys.SelectMany(k => target[k]).ToList();
List<string> existingFiles = new List<string>();
foreach (ProjectItem parentItem in current.Keys.ToList())
{
foreach (string filename in current[parentItem])
{
if (!allTargetFiles.Contains(filename) && !fileNames.Contains(filename)) // here
dte.Solution.FindProjectItem(filename)?.Delete();
else
existingFiles.Add(filename);
}
}
// just to be safe
existingFiles = existingFiles.Distinct().ToList();
foreach (ProjectItem parentItem in target.Keys.ToList())
{
foreach (string filename in target[parentItem].Except(existingFiles).ToList())
parentItem.ProjectItems.AddFromFile(filename);
}
}
Suggestion:
I have solved this issue by deleting files if the specified file is in the directory of target files
I copied the EFModelFileManager.ttinclude file to model location and added a function to determine for deleting like below(code not optimized)
bool shouldDelete(string[] targetFileNames, string fileName)
{
Dictionary<string, string> directories = new Dictionary<string, string>();
foreach (string targetFilename in targetFileNames)
{
string? directory = Path.GetDirectoryName(targetFilename);
if (directory != null)
{
if (!directories.ContainsKey(directory))
directories.Add(directory, targetFilename);
}
}
return directories.ContainsKey(Path.GetDirectoryName(fileName));
}
and then,
private void ProjectSync(IEnumerable<string> keepFileNames)
{
Dictionary<ProjectItem, List<string>> current = GetCurrentState();
string[] fileNames = keepFileNames as string[] ?? keepFileNames.ToArray();
Dictionary<ProjectItem, List<string>> target = GetTargetState(fileNames);
List<string> allTargetFiles = target.Keys.SelectMany(k => target[k]).ToList();
List<string> existingFiles = new List<string>();
foreach (ProjectItem parentItem in current.Keys.ToList())
{
foreach (string filename in current[parentItem])
{
if (!allTargetFiles.Contains(filename) && shouldDelete(fileNames, filename)) // changed
dte.Solution.FindProjectItem(filename)?.Delete();
else
existingFiles.Add(filename);
}
}
// just to be safe
existingFiles = existingFiles.Distinct().ToList();
foreach (ProjectItem parentItem in target.Keys.ToList())
{
foreach (string filename in target[parentItem].Except(existingFiles).ToList())
parentItem.ProjectItems.AddFromFile(filename);
}
}
This worked for me.
Hope this helps.