我看到了一些奇怪的东西,它跟我的预期不太一样。
我们来看这段简单的代码,让你了解我做了什么:
MyRepository db = new MyRepository();
// let's get them all
IQueryable<TblCals> cals = db.FindAllCalendars();
// now that we have everything, let's split up
List<TblCals> masters = cals.Where(x => x.IsMaster).ToList();
List<TblCals> childs = cals.Where(x => x.Parent > 0).ToList();
// Let's change the name of the masters
foreach(var c in masters) c.Name = String.Concat("Master: ", c.Name);
// Let's send everything to the View
return View(new model() { masters, childs });
现在,问题是:
为什么更改List masters中的名称也会更改childs中对象的名称?
当我执行List masters = cals.Where(x => x.IsMaster).ToList()时,它不应该从cals对象复制元素而不仅仅是引用它们吗?
我可以简单地执行:我该怎么做来防止这种行为?
MyRepository db = new MyRepository();
// let's get them all
IQueryable<TblCals> cals = db.FindAllCalendars();
// now that we have everything, let's split up
List<TblCals> masters = db.FindAllCalendarsThatAreMasters().ToList();
List<TblCals> childs = db.FindAllCalendarsThatHaveParent().ToList();
但是这将导致 3 次数据库查询,我可以先获取所有内容,然后再使用那个对象...但是如果我从中更改了任何子查询,“主”对象也会随之更改。
所有这背后的主要想法是看看是否安全进行以下操作:
public IEnumerable<JK_Users> ListAllUsers() {
// Check / Add to memcache
string key = "ListAllUsers";
var users = MemcachedLayer.Get<IEnumerable<JK_Users>>(key);
if(key == null)
users = db.Tbl_Users.CachedQuery(key);
return users;
}
public IEnumerable<JK_Users> FindUserById(decimal id) {
// call ListAllUsers() instead Repository
return this.ListAllUsers().FirstOrDefault(x => x.user_id == id);
}
public IEnumerable<JK_Users> FindUserByUsername(string username) {
// call ListAllUsers() instead Repository
return this.ListAllUsers().FirstOrDefault(x => x.username == username);
}
或者我必须调用
public JK_Users FindUserById(decimal id) {
return db.Tbl_Users.FirstOrDefault(x => x.user_id == id);
}
public JK_Users FindUserByUsername(string username) {
return db.Tbl_Users.FirstOrDefault(x => x.username == username);
}
这样我就可以更有效地使用缓存。