Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Code First Migrations causing CA1701 and CA1703

Upon enabling migrations for my code-first EF 5 context I started to receive a TON of CA1701 and CA1703 code analysis violations due to the migration history string being added to the project's resx file.

I do not care to disable CA1701 and CA1703 and also do not want to suppress 100ish messages for each individual migration that's going to be added. Is there a way to mark a resx's xml file or individual resx entry as // <auto-generated /> so this stops happening? If I have to disable the two rules, then so be it just hoping that's not the only sane answer!

TIA Jason

like image 347
Werewolf Avatar asked Dec 12 '22 12:12

Werewolf


2 Answers

I personally got fed up with manually keeping my suppressions up to date (after 2 hours), so I wrote the following T4 template:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Runtime.Remoting.Messaging" #>
<#@ output extension=".cs" #>
using System.Diagnostics.CodeAnalysis;

<#
    var @namespace = CallContext.LogicalGetData("NamespaceHint");
    var folder = Path.GetDirectoryName(Host.TemplateFile);

    const int timestampLength = 15;
    var timestampWildcards = new string('?', timestampLength);
    var paths = Directory.EnumerateFiles(folder, timestampWildcards + "_*.cs");

    const int timestampUnderscoreLength = timestampLength + 1;

    var classNames = from path in paths
                     let fileName = Path.GetFileNameWithoutExtension(path)
                     where !fileName.EndsWith(".designer", StringComparison.OrdinalIgnoreCase)
                     where fileName.Length> timestampUnderscoreLength 
                     select fileName.Substring(timestampUnderscoreLength);

    foreach(var className in classNames)
    {
        var fullClassName = @namespace + "." + className;
#>
[assembly: SuppressMessage("Microsoft.Naming", "CA1701:ResourceStringCompoundWordsShouldBeCasedCorrectly", Scope = "resource", Target = "<#=fullClassName#>.resources")]
[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "<#=fullClassName#>.resources")]
<#
    }
#>

Create a T4 template with this content in the same folder as the migrations, the generated code will automatically contain suppressions for the resources, e.g.

[assembly: SuppressMessage("Microsoft.Naming", "CA1701:ResourceStringCompoundWordsShouldBeCasedCorrectly", Scope = "resource", Target = "LzSoftware.Collectables.Domain.EntityFramework.Migrations.InitialCreation.resources")]
[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "LzSoftware.Collectables.Domain.EntityFramework.Migrations.InitialCreation.resources")]
[assembly: SuppressMessage("Microsoft.Naming", "CA1701:ResourceStringCompoundWordsShouldBeCasedCorrectly", Scope = "resource", Target = "LzSoftware.Collectables.Domain.EntityFramework.Migrations.RemovedAdministratorRoleFromSettings.resources")]
[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "LzSoftware.Collectables.Domain.EntityFramework.Migrations.RemovedAdministratorRoleFromSettings.resources")]
like image 66
Lukazoid Avatar answered Jan 15 '23 09:01

Lukazoid


I just noticed this today, myself. You can suppress the CA1701 and CA1703 warnings at the resource level with the following in either your AssemblyInfo.cs or a GlobalSuppressions.cs file:

[assembly: SuppressMessage("Microsoft.Naming",
    "CA1701:ResourceStringCompoundWordsShouldBeCasedCorrectly",
    Justification = "The auto-genererated code from code first migrations trigger this warning.",
    Scope = "resource", Target = "Full.Namespace.To.Your.Migrations.NameOfYourMigration.resources")]
[assembly: SuppressMessage("Microsoft.Naming",
    "CA1703:ResourceStringsShouldBeSpelledCorrectly",
    Justification = "The auto-genererated code from code first migrations trigger this warning.",
    Scope = "resource", Target = "Full.Namespace.To.Your.Migrations.NameOfYourMigration.resources")]

You'll need to do this for each of your migrations, but it's much better than suppressing each warning individually.

like image 25
Lance Held Avatar answered Jan 15 '23 09:01

Lance Held