2012-06-26 64 views
3

對於實體框架和調查將一些傳統數據訪問代碼轉換爲使用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對象時相似,它只從Products屬性獲取ProductId並將值保存在數據庫中。

+0

我不知道任何關於EF 4.X的支持。那麼如何將id(productid)屬性映射到數據庫,但不映射關係屬性(Product)?您可以在您的實體中實施產品屬性。與您的解決方案類似的東西。 – yonexbat

回答

0

如果您加載CustomerProduct屬性時,將自動從內存中只要填寫無需查詢數據庫關聯到客戶已經連接的產品附上您的產品實例的EF上下文即可。

例如,開始與這些實體:

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

最後,使樣品完整和可運行我們播種的數據庫,要求客戶並打印相關的產品說明:如果附加探查到SQL Server,你會發現,客戶從加載

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

數據庫,但由於已經連接到上下文,因此不會執行查詢來獲取產品。這適用於加載客戶時以及使用相關產品保存新客戶時的情況。

聲明:我不是EF專家,所以這種方法可能會產生一些我不能想到的不良副作用。

+0

今天晚些時候我會試試你的解決方案,看看它是如何發展的。 – softveda

+0

你的解決方案確實有用,因此我給你賞金。它至少給了我至少一個進一步研究的方向。但我必須弄清楚這是否是一種實用的解決方案。附加1000個我緩存在每個上下文對象創建上的不同類型對象的成本可能太昂貴了。 – softveda

相關問題