gpt4 book ai didi

c# - 使用 Entity Framework 时了解对象

转载 作者:行者123 更新时间:2023-11-30 16:27:10 25 4
gpt4 key购买 nike

我看到了一些奇怪的东西,这不是我所期待的。

让我们用这个简单的代码让你看看我做了什么:

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<TblCals> masters = cals.Where(x => x.IsMaster).ToList();这不应该复制元素而不是仅从 cals 中引用它们吗?对象?

What can I do to prevent this behavior?

我可以简单地做:

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

所以我可以更有效地使用缓存。

最佳答案

不,集合只包含引用类型的引用。这里没有特定于 EF 的内容:

List<StringBuilder> list1 = new List<StringBuilder>();
List<StringBuilder> list2 = new List<StringBuilder>();
StringBuilder builder = new StringBuilder();
list1.Add(builder);
list2.Add(builder);
list1[0].Append("Foo");
Console.WriteLine(list2[0]); // Still prints Foo...

Entity Framework 确保对于任何一个“实体”,只有一个对象(在您的存储库对象的上下文中)。这意味着您无法进入在表示同一实体(其中实体由其 ID 定义)的两个不同对象上更改相同字段的状态。

这确实是合乎逻辑的方法 - 将涉及的值视为实体;您的两个查询与某些结果的相同实体匹配...为什么您希望同一实体的这两个结果是独立的对象?如果有人提到“Stack Overflow 的 Jon Skeet”和“英国雷丁 Tilehurst 的 Jon Skeet”,那是同一个人 - 通过一个结果更改(比如说)年龄应该通过另一个结果。

关于c# - 使用 Entity Framework 时了解对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8150110/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com