1

使用下面的代碼我在運行時生成使用CSharpCodeProvider

  string code = @" 
      using System.Data.Entity; 
      using GenerateContext.Models; 
      using System.Data.Entity.Core.EntityClient; 
      using GenerateContext.Models.Mapping; 

      namespace GenerateContext.Models 
      { 
public partial class OnlineShopContext : DbContext 
{ 
    static OnlineShopContext() 
    { 
     Database.SetInitializer<OnlineShopContext>(null); 
    } 

    public OnlineShopContext() 
     : base(""Name = OnlineShopContext"") 
    { 
     } 

    public DbSet<Customer> Customers { get; set; } 
    public DbSet<Order> Orders { get; set; } 
    public DbSet<OrderItem> OrderItems { get; set; } 
    public DbSet<Product> Products { get; set; } 


    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new CustomerMap()); 
     modelBuilder.Configurations.Add(new OrderMap()); 
     modelBuilder.Configurations.Add(new OrderItemMap()); 
     modelBuilder.Configurations.Add(new ProductMap()); 
    } 

} 
} 
"; 

     CSharpCodeProvider provider = new CSharpCodeProvider(); 
     CompilerParameters parameters = new CompilerParameters(); 

     // Reference to System.Drawing library 
     parameters.ReferencedAssemblies.Add("System.Drawing.dll"); 
     parameters.ReferencedAssemblies.Add("System.Data.dll"); 
     parameters.ReferencedAssemblies.Add("System.Data.Entity.dll"); 
     parameters.ReferencedAssemblies.Add("System.ComponentModel.dll"); 
     parameters.ReferencedAssemblies.Add(typeof(Customer).Assembly.Location); 
         parameters.ReferencedAssemblies.Add(typeof(CustomerMap).Assembly.Location); 
         parameters.ReferencedAssemblies.Add(typeof(DbSet).Assembly.Location); 
         parameters.ReferencedAssemblies.Add(typeof(DbContext).Assembly.Location); 
         parameters.ReferencedAssemblies.Add(typeof(IQueryable).Assembly.Location); 
             parameters.ReferencedAssemblies.Add(typeof(IQueryable<>).Assembly.Location); 
         parameters.ReferencedAssemblies.Add(typeof(System.ComponentModel.IListSource).Assembly.Location); 

     parameters.GenerateExecutable = false; 
     parameters.GenerateInMemory = false; 
     parameters.OutputAssembly = "OutputAssembly.dll"; 

     CompilerResults results = provider.CompileAssemblyFromSource(parameters, code); 

     if (results.Errors.HasErrors) 
     { 
      StringBuilder sb = new StringBuilder(); 

      foreach (CompilerError error in results.Errors) 
      { 
       sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText)); 
      } 

      throw new InvalidOperationException(sb.ToString()); 
     } 

並且將所生成組件生成OnlineShopContext的DbContext是:(使用ILSpy)

using GenerateContext.Models.Mapping; 
using System; 
using System.Data.Entity; 

namespace GenerateContext.Models 
{ 
public class OnlineShopContext : DbContext 
{ 
    public DbSet<Customer> Customers 
    { 
     get; 
     set; 
    } 

    public DbSet<Order> Orders 
    { 
     get; 
     set; 
    } 

    public DbSet<OrderItem> OrderItems 
    { 
     get; 
     set; 
    } 

    public DbSet<Product> Products 
    { 
     get; 
     set; 
    } 

    static OnlineShopContext() 
    { 
     Database.SetInitializer<OnlineShopContext>(null); 
    } 

    public OnlineShopContext() : base("Name = OnlineShopContext") 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add<Customer>(new CustomerMap()); 
     modelBuilder.Configurations.Add<Order>(new OrderMap()); 
     modelBuilder.Configurations.Add<OrderItem>(new OrderItemMap()); 
     modelBuilder.Configurations.Add<Product>(new ProductMap()); 
    } 
} 

}

當我想創建實例並運行查詢,例如FirstOrDeafult或Where,這些方法不在那裏。但是有Find方法,因爲不匹配的數據類型而不能運行,這很奇怪

 Assembly assembly = results.CompiledAssembly; 
     Type type = assembly.GetType("GenerateContext.Models.OnlineShopContext"); 
     dynamic db = (DbContext)Activator.CreateInstance(type); 
     var obj = db.Customers.GetType(); 
     MethodInfo main = obj.GetMethod("Find"); 
     object[] parametersArray = new object[] { 100 }; 
     var customer = main.Invoke(obj, parametersArray); 

我該怎麼辦? 如何將實例投入某個類型並使用它強烈地鍵入以獲取Where或FirstOrDefault的數據

+0

'Where'和'FirstOrDefault'是擴展方法。它們可以在'System.Linq.Queryable'類型中找到 – jbl

回答

0

終於我做到了。

public System.Data.Entity.DbSet<T> Get<T>() where T : class 
    { 
     var dllversionAssm = Assembly.LoadFile(debugPath+"OutputAssembly.dll"); 
     Type type = dllversionAssm.GetType("GenerateContext.Models.OnlineShopContext"); 
     DbContext db = (DbContext)Activator.CreateInstance(type); 
     var set = db.Set<T>(); 
     return set; 
    } 
0

如果我將db.Customers轉換爲System.Data.Entity.DbSet<Customer>,它就可以工作。像下面

 var dllversionAssm = Assembly.LoadFile(@debugPath+"OutputAssembly.dll"); 
     Type type = dllversionAssm.GetType("GenerateContext.Models.OnlineShopContext"); 
     dynamic db = (DbContext)Activator.CreateInstance(type); 
     var customerService = ((System.Data.Entity.DbSet<Customer>)db.Customers); 
     var customer = customerService.FirstOrDefault(q => q.Id == 100); 

現在,我怎麼能施放任何動態類型,以它的實體類型,例如db.Orders到System.Data.Entity.DbSet<Order>或db.Products到System.Data.Entity.DbSet<Product>。我的意思是我怎樣纔能有一個通用的方法來做到這一點?