gpt4 book ai didi

entity-framework - 如何使用 Entity Framework 从数据库实现自定义对象具体化

转载 作者:行者123 更新时间:2023-12-03 07:15:59 26 4
gpt4 key购买 nike

我对 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 对象

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;
}

我的问题是,使用 EF 实现这一点是可能的,当它具体化 Customer 对象时,它不是从 DB 而是通过另一种方法(在本例中是从内存缓存)设置 Product 属性。类似地,当保存新的 Customer 对象时,它仅从 Products 属性获取 ProductId 并将该值保存在数据库中。

最佳答案

如果您将产品实例附加到 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 专家,因此这种方法可能会产生一些我无法考虑的不良副作用。

关于entity-framework - 如何使用 Entity Framework 从数据库实现自定义对象具体化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11205766/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com