Domanda

I have a T4 template which generates a DbContext and a migration configuration. During runtime, I use that template to create an assembly, then use that assembly to generate a migration. However, when I want to do an update database, still programmatically. I get an error, however:

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "EFMigrations._11_01_30.resources" was correctly embedded or linked into assembly "AutomatedMigrations" at compile time, or that all the satellite assemblies required are loadable and fully signed.

The code for creating the assembly:

var configuration = (DbMigrationsConfiguration)icc.CompiledAssembly.CreateInstance("EFMigrations.Configuration");
File.WriteAllText(directory + scaffold.MigrationId + ".designer.cs", scaffold.DesignerCode);
File.WriteAllText(directory + scaffold.MigrationId + ".cs", scaffold.UserCode);

using (var writer = new ResXResourceWriter(directory + scaffold.MigrationId + ".resources"))
{
    foreach (var resource in scaffold.Resources)
        writer.AddResource(resource.Key, resource.Value);
}

var filesContents = Directory.GetFiles(directory).Where(x => x.EndsWith(".cs")).Select(File.ReadAllText).ToList();
var resources = Directory.GetFiles(directory).Where(x => x.EndsWith(".resources"));
compilerParams.EmbeddedResources.AddRange(resources.ToArray());

var assemblies = provider.CompileAssemblyFromSource(compilerParams, filesContents.ToArray());
configuration.MigrationsAssembly = assemblies.CompiledAssembly;
configuration.MigrationsNamespace = "EFMigrations";
var migrator = new DbMigrator(configuration);
migrator.Update();

The exception is thrown on the Update() line.

Update:

I've performed a small hack to resolve that issue (by naming my resource Namespace.Class.resources, however now I am getting an error:

Stream is not a valid resource file

Update 2:

I have resolved the issue by creating another T4 runtime template and placing the values from the resources directly into it. It's a hackish solution, but it works for my purposes. However I'm still annoyed by the behaviour of the resource file and why it doesn't like the generated resource file.

È stato utile?

Soluzione

Just to mark this as answered - I have resolved my particular issue by creating another t4 generator which uses a sample of the designer code as base and fills in MigrationMetadataID and Target with the ones from scaffold resources like this:

var designerGenerator = new MigrationDesignerGenerator();
designerGenerator.Session = new Dictionary<string, object>();
designerGenerator.Session.Add("Target", scaffold.Resources["Target"]);
designerGenerator.Session.Add("MigrationId", scaffold.MigrationId);
designerGenerator.Initialize();
File.WriteAllText(directory + scaffold.MigrationId + ".Designer.cs", designerGenerator.TransformText());

I have excluded the ResourceManager field from the metadata generator, and used this as target instead:

string IMigrationMetadata.Target
{
    get { return "<#= Target #>"; }
}

I have come no further to solving the Resx file issue, but I will forget this for now - as hackish as this feels, it works and it works well based on my tests.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top