Saa*_*ail 7 c# eager-loading linq-to-sql self-reference
我有2个相关的Linq to SQL问题.请参阅下面的图片,看看我的模型是什么样的.
问题1
我想知道如何User.AddedByUser在我的User 类/表上加载字段.该字段由字段上的关系生成User.AddedByUserId.该表是自引用的,我试图弄清楚如何让Linq to SQL User.AddedByUser急切地加载属性,即无论何时User加载/获取任何实体,它还必须获取User.AddedByUser和User.ChangedByUser.但是,据我所知,这可能会成为一个递归问题......
更新1.1:
我试过使用DataLoadOptions如下:
var options = new DataLoadOptions();
options.LoadWith<User>(u => u.ChangedByUser);
options.LoadWith<User>(u => u.AddedByUser);
db = new ModelDataContext(connectionString);
db.LoadOptions = options;
Run Code Online (Sandbox Code Playgroud)
但这不起作用,我在第2行得到以下异常:
System.InvalidOperationException occurred
Message="Cycles not allowed in LoadOptions LoadWith type graph."
Source="System.Data.Linq"
StackTrace:
at System.Data.Linq.DataLoadOptions.ValidateTypeGraphAcyclic()
at System.Data.Linq.DataLoadOptions.Preload(MemberInfo association)
at System.Data.Linq.DataLoadOptions.LoadWith[T](Expression`1 expression)
at i3t.KpCosting.Service.Library.Repositories.UserRepository..ctor(String connectionString) in C:\Development\KP Costing\Trunk\Code\i3t.KpCosting.Service.Library\Repositories\UserRepository.cs:line 15
InnerException:
Run Code Online (Sandbox Code Playgroud)
异常是不言自明的 - 对象图不允许是循环的.另外,假设第2行没有抛出异常,我很确定第3行会,因为它们是重复键.
更新1.2:
以下内容也不起作用(不与上面的Update 1.1结合使用):
var query = from u in db.Users
select new User()
{
Id = u.Id,
// other fields removed for brevityy
AddedByUser = u.AddedByUser,
ChangedByUser = u.ChangedByUser,
};
return query.ToList();
Run Code Online (Sandbox Code Playgroud)
它引发了以下不言自明的异常:
System.NotSupportedException occurred
Message="Explicit construction of entity type 'i3t.KpCosting.Shared.Model.User' in query is not allowed."
Run Code Online (Sandbox Code Playgroud)
我现在真的不知道如何解决这个问题.请帮忙!
问题2
在我的数据库中的每个其他表,因此Linq到SQL模型,我有两个字段,Entity.ChangedByUser(链接到Entity.ChangedByUserId外键/关系)和Entity.AddedByUser(链接到Entity.AddedByUserId外键/关系)
如何让Linq to SQL为我加载这些字段?我是否需要对查询进行简单的连接?或者还有其他方法吗?
也许你可以尝试退后一步,看看你想对这段关系做什么?我假设您想向用户显示此信息,例如“由 Iain Galloway 8 小时前修改”。
像下面这样的东西可以工作吗?:-
var users = from u in db.Users
select new
{
/* other stuff... */
AddedTimestamp = u.AddedTimestamp,
AddedDescription = u.AddedByUser.FullName,
ChangedTimestamp = u.ChangedTimestamp,
ChangedDescription = u.ChangedByUser.FullName
};
Run Code Online (Sandbox Code Playgroud)
为了(imo)清晰起见,我在那里使用了匿名类型。如果您愿意,可以将这些属性添加到您的用户类型中。
至于你的第二个问题,你正常的 LoadWith(x => x.AddedByUser) 等应该工作得很好 - 尽管我倾向于将描述字符串直接存储在数据库中 - 你在描述更新之间进行了权衡当 ChangedByUser.FullName 更改时,如果 ChangedByUser 被删除,则必须执行一些复杂且可能违反直觉的操作(例如 ON DELETE CASCADE,或在代码中处理 null ChangedByUser)。
| 归档时间: |
|
| 查看次数: |
5318 次 |
| 最近记录: |