使用LINQ to SQL时如何初始化瞬态值?

时间:2013-03-09 11:36:37

标签: c# linq-to-sql

我有一个DataContext和一个表,定义如下:

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 */

任何想法最好的办法是什么?

2 个答案:

答案 0 :(得分: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构造函数。

答案 1 :(得分: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 to SQL(获取所有元素)和LINQ to Objects(使用构造函数创建新元素)之间拆分执行所必需的。它也可以替换为AsEnumerable()