我对Entity Framework相当新,并研究将一些遗留数据访问代码转换为使用EF。我想知道EF中是否可以使用以下内容,如果是的话。 假设我有一个像这样的客户表
CustomerId | ProductId | StartDate | EndDate
--------------------------------------------
100 | 999 | 01/01/2012| null
假设我还将产品数据从其他地方(如XML文件)加载为产品对象的缓存。
public class Customer
{
public int CustomerId {get;set;}
public int Product {get;set}
public DateTime StartDate {get;set;}
public DateTime? EndDate {get;set;}
}
public class Product
{
public int ProductId {get;set;}
public int Description {get;set}
}
目前在CustomerDal类中,该方法使用StoredProc来获取像这样的
客户对象Customer GetCustomer(int customerId)
{
// setup connection, command, parameters for SP, loop over datareader
Customer customer = new Customer();
customer.CustomerId = rdr.GetInt32(0);
int productId = rdr.GetInt32(1);
// ProductCache is a singleton object that has been initialised before
customer.Product = ProductCache.Instance.GetProduct(productId);
customer.StartDate = rdr.GetDateTime(2);
customer.EndDate = rdr.IsDbNull(3) ? (DateTime?)null : rdr.GetDateTime(3);
return customer;
}
我的问题是,当它实现Customer对象时,它可能使用EF,它不是从DB设置Product属性,而是通过另一种方法设置,在本例中是从内存缓存中设置。类似地,在保存新的Customer对象时,它只从Products属性获取ProductId并将值保存在DB中。
答案 0 :(得分:0)
如果您将产品实例附加到EF上下文,那么在加载Customer
时,只要与数据库关联的产品,Product
属性将自动从内存中填充而无需查询数据库。客户已经附上了。
例如,从这些实体开始:
public class Customer
{
public int Id { get; set; }
public int ProductId { get; set; }
public string Name { get; set; }
public Product Product { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Description { get; set; }
}
产品将在全球范围内提供,为简单起见,我们将其设为静态类:
public static class CachedProducts
{
public static Product[] All
{
get
{
return new Product[] { new Product { Id = 1, Description = "Foo" } };
}
}
}
考虑到这一点,我们只需要确保每个EF上下文都以附加到它的所有产品开头:
public class CustomerContext : DbContext
{
public CustomerContext()
{
// Attach products to context
Array.ForEach(CachedProducts.All, p => this.Products.Attach(p));
}
public DbSet<Customer> Customers { get; set; }
public DbSet<Product> Products { get; set; }
}
最后,为了使样本完整且可运行,我们为数据库设定种子,请求客户并打印相关的产品说明:
public class DatabaseInitializer : CreateDatabaseIfNotExists<CustomerContext>
{
protected override void Seed(CustomerContext context)
{
var p = new Product { Id = 1, Description = "Foo" };
var c = new Customer { Id = 1, Product = p, Name = "John Doe" };
context.Customers.Add(c);
context.SaveChanges();
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer<CustomerContext>(new DatabaseInitializer());
using (var context = new CustomerContext())
{
var customer = context.Customers.Single(c => c.Id == 1);
Console.WriteLine(customer.Product.Description);
}
}
}
如果将分析器附加到SQL Server,您会注意到客户是从数据库加载的,但是由于它已经附加到上下文,因此不会执行任何查询来获取产品。这在加载客户时以及使用关联产品保存新客户时都有效。
免责声明:我不是EF专家,因此这种方法可能会产生一些我不能考虑的不良副作用。