2013-03-09 13 views
0

У меня есть DataContext и таблицу, определенную следующим образом:Как инициализировать значения переходных процессов при использовании LINQ to SQL?

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) конструктор в любом случае:

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

Однако , если я хочу получить пучок строк из базы данных, переходные члены, конечно, не будут установлены. Мне нужно будет их инициализировать, прежде чем выполнять какую-либо работу с извлеченными объектами.

Единственное решение, о котором я могу думать, - это сделать членов глобальными и пройти через все запрошенные объекты и установить их перед выполнением любых других операций с ними. Но это не опрятно:

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 по-прежнему поддерживать идентификацию запрошенных объектов, т. Е. Если один из них будет делать один и тот же запрос дважды, будет ли он возвращать те же объекты (что и в обычном случае)? –

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() необходимо разделить выполнение между LINQ к SQL (получать все элементы) и LINQ к объектам (создание новых элементов с помощью вашего конструктора). Он также может быть заменен на AsEnumerable().

Смежные вопросы