2013-03-09 70 views
0

我有一個DataContext和一個表,像這樣定義的:如何在使用LINQ to SQL時初始化瞬態值?

MyDataContext db = new MyDataContext(someLocation); 
MyItem myItem = new MyItem(db, someObj); 
db.MyItems.Add(myItem); 
db.SubmitChanges(); 

但是:

public class MyDataContext : DataContext 
{ 
    public Table<MyItem> MyItems; 

    public MyDataContext(string location) : base(location) { } 
} 

[Table(Name = "MyItems")] 
public class MyItem 
{ 
    // ID 
    private string id; 

    [Column(Storage = "id", IsPrimaryKey = true, IsDbGenerated = true, DbType = "int NOT NULL IDENTITY")] 
    public string Id 
    { 
     get { return id; } 
     private set { id = value; } 
    } 

    private MyDataContext db; 
    private MyTransitiveObject obj; 

    public MyItem() {} 

    public MyItem(MyDataContext db, MyTransitiveObject obj) 
    { 
     this.db = db; 
     this.obj = obj; 
    } 
} 

當我創建表中的新MyItem,那裏我稱之爲MyItem(MyDataContext db, MyTransitiveObject obj)構造反正也沒問題,如果我想從數據庫中檢索一堆行,那麼傳遞成員當然不會被設置。我需要初始化它們,然後才能對檢索到的對象進行任何操作。

我能想到的唯一解決方案是使成員全局爲並遍歷所有查詢的對象並在對它們進行任何其他操作之前對其進行設置。但這並不簡潔:

var q = 
    from c in db.Customers 
    select c; 

var list = q.ToList(); 

foreach (MyItem m in list) 
{ 
    q.Db = db; 
    q.Obj = someObj; 
} 

/* Do something with list */ 

任何想法什麼是最好的辦法來處理這可能是?

回答

1

你可以做這樣的事情:

var q = from c in db.Customers 
     select new MyItem 
     { 
      Id = c.Id, 
      // copy rest of c to MyItem 
      Db = db, 
      Obj = someObj 
     }; 

這個部分是轉換到查詢,所以你不必遍歷結果集。雖然需要將每個對象的上下文存儲起來似乎很奇怪。

雖然它確實意味着,如果添加額外的列到你的表,你必須更新MyItem構造。

+0

謝謝,克里斯! DataContext是否仍然能夠維護被查詢對象的身份,即如果兩次進行相同的查詢,是否仍然返回相同的對象(如通常情況下那樣)? – 2013-03-09 16:31:30

0

我不知道爲什麼你想存儲的每一個元素中的上下文和數據庫的參考。我認爲你應該首先重新考慮你的設計。

您可以擴展您的select語句以使用您的構造函數創建元素,但無法將其轉換爲SQL,因此您必須首先獲取元素。但是,您不必公開您的字段。

var q = 
    from c in db.Customers 
    select c; 

var list = q.ToList() 
      .Select(e => new MyItem(db, someObj) { Id = e.Id }) 
      .ToList(); 

q.ToList()是必要的SQL(獲得的所有元素)和LINQ LINQ之間的分裂執行到對象(創建使用構造新的元素)。它也可以替換爲AsEnumerable()