使用下面的代碼我在運行時生成使用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的數據
'Where'和'FirstOrDefault'是擴展方法。它們可以在'System.Linq.Queryable'類型中找到 – jbl