在自引用表中急切地将Linq加载到SQL实体

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为我加载这些字段?我是否需要对查询进行简单的连接?或者还有其他方法吗?

Linq to SQL eager loading on self referencing table http://img245.imageshack.us/img245/5631/linqtosql.jpg

Iai*_*way 3

也许你可以尝试退后一步,看看你想对这段关系做什么?我假设您想向用户显示此信息,例如“由 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)。