T4 - Entity Framework Error: Method not found: 'System.Data.Entity.DbSet`1

前端 未结 1 1696
不思量自难忘°
不思量自难忘° 2021-01-14 08:46

Trying to create a fairly simple T4 which I\'m trying to load some values that I can use for later:

<#@ template debug=\"false\" hostspecific=\"false\" la         


        
1条回答
  •  离开以前
    2021-01-14 09:34

    The classes in the same project of T4 template is not visible by it, and to simplify its debugging, the following is a step by step to run T4 successfully in EntityFramework without problem and ease of debugging:

    step 1: Create a separate class library project for the model

    Create a separate class library project for the model, to be referenced by your application and T4 template.

    That also simplify unit test and resolve many problems with T4.

    Step2 : resolving Connection String

    To avoid the problems of configuration file and configure the connectionString correctly, create a partial class which extend the Context class to avoid overwriting when re-generate the context. Define new overload constructor.

    for example, NorthwindEntities

          using System.Data.Entity;
         namespace NorthWin
         {        
            public partial class NorthwindEntities : DbContext
            {
                public NorthwindEntities(string connString)
                    : base(connString)
                {
                }
            }
        }
    

    step3: Create all DAL methods in separate class(s)

    All methods that you need in T4 template,create it in separate class(es) in the same class library project and call them from T4 template.

    Define the connectionString explicitly in your class (note the single quote in the connection string). Edit: or you can use the include template. example:

        using System.Linq;
        namespace NorthWin
        {
            public class DAL
            {
    
                string ConnectionString = @"metadata=res://*/NorthWind.csdl|res://*/NorthWind.ssdl|res://*/NorthWind.msl;provider=System.Data.SqlClient;provider connection string='data source=myserver;initial catalog=Northwind;persist security info=True;user id=xxx;password=yyy;MultipleActiveResultSets=True;App=EntityFramework';";
    
       public DAL (string connString)
        {
          ConnectionString =connString;
        }       
        public int GetCustomerCount()
                {
                    var n = 0;
                // call ye new overload constructor
                    using (var ctx = new NorthwindEntities(ConnectionString))
                    {
                        n = ctx.Customers.Count();
                    }
                    return n;
                }
            }
        }
    

    step 4: build your T4 Define the minimum assemblies for EntityFramework and Call DAL methods

    example

        <#@ template debug="false" hostspecific="true" language="C#" #>
        <#@ output extension=".txt" #>
    
          <#@ assembly name="System.Xml"#>
        <#@ assembly name="$(TargetDir)NorthWin.dll" #>
        <#@ assembly name="$(TargetDir)EntityFramework.dll" #>
        <#@ assembly name="$(TargetDir)EntityFramework.SqlServer.dll" #>
        <#@ assembly name="EnvDTE" #>
        <#@ assembly name="System.Configuration" #>
    
        <#@ import namespace="System.Configuration" #>
        <#@ import namespace="System" #>
         <#@ import namespace="System.Linq" #>
        <#@ import namespace="System.Collections.Generic" #>
         <#@ import namespace="NorthWin" #>
        <#
    
           int n=0;
            var dal = new DAL();
           / /call DAL methods
            n= dal.GetCustomerCount();
    
         #> 
    
        <#= n #>
        {
          ... // More code here. 
        }
    

    Output of T4 Template:

    114
    {
      ... // More code here. 
    }
    

    Edit:

    You can get the connectionString from configuration file using the include file as described in:

    Injecting Your Web.Config Connection String Into Your T4 Template

    then you pass the connectionString to your DAL classes with constructor that accept connection String.

    in your template add this code

    <#@ include file="ConfigurationAccessor.ttinclude" #>
    <# 
     var config = new ConfigurationAccessor((IServiceProvider)this.Host,  @"path\to\ProjectWithConfig.csproj");
     string connectionString =   config.ConnectionStrings["MainConnectionString"].ConnectionString;
    #>
    

    0 讨论(0)
提交回复
热议问题