【发布时间】:2014-06-11 02:54:01
【问题描述】:
我的用户具有以下类结构,以及他们对可能关联的不同公司的权限:
public class User
{
public Guid Id { get; set; }
public List<Permission> Permissions { get; set; }
public Company DefaultCompany { get; set; }
}
public class Permission
{
public User User { get; set; }
public Company Company { get; set; }
public int PermissionLevel { get; set; }
}
public class Company
{
public Guid Id { get; set; }
public string Name { get; set; }
}
这会产生三个 SQL 表。 Permission.User_Id > User.Id 和 Permission.Company_Id > Company.Id 之间有一个 FK。 User.DefaultCompany 和 Company 表之间没有 显式 关系(即 FK)。这是故意的,因为我们的数据库架构中有一个遗留选择。
我还有一个数据库存储库方法,它通过用户 ID 获取用户,并包含完整的公司记录:
public User GetById(Guid Id)
{
return (from r in this.Context.Users.Include("Permissions.Company")
where r.Id == Id
select r)
.SingleOrDefault();
}
这工作正常,但它没有设置DefaultCompany 属性。所以我尝试通过将此方法更改为以下方法来设置它。值得指出的是,代表 DefaultCompany 的 Company 记录与 User 共享相同的 ID 值。
public User GetById(Guid Id)
{
return (from r in this.Context.Users.Include("Permissions.Company")
where r.Id == Id
join c in this.Context.Companies on r.Id equals c.Id into companies
from company in companies.DefaultIfEmpty()
select new { User = r, Company = company })
.ToList()
.Select(p => { p.User.DefaultCompany = p.Company; return p.User; })
.SingleOrDefault();
}
事实上,这确实设置了DefaultCompany,但它具有不选择Permissions 列表的副作用。我可以将这一切作为两个单独的操作来完成,如下面的代码所示,但如果没有必要,我宁愿不要两次访问数据库。
public User GetById(Guid Id)
{
var u = (from r in this.Context.Users.Include("Permissions.Company")
where r.Id == Id
select r)
.SingleOrDefault();
u.DefaultCompany = (from r in this.Context.Companies where r.Id == u.Id select r).SingleOrDefault();
return u;
}
还有其他方法可以做到这一点吗?
编辑:解释生成的 SQL 数据模型和其他示例。
【问题讨论】:
-
很难理解你的数据库模型。您能否更清楚地解释实体之间的关系,甚至显示模式?哪个是权限的关键?我认为您的问题来自模型本身,而不是您进行查询的方式。
-
@JotaBe 我已经编辑了我的问题。很抱歉不清楚 - 数据模型比我在这里记录的要复杂和遗留,但我试图掌握两个查询之间的潜在差异以及为什么添加连接会导致权限列表不被填充.
-
现在清楚多了。没有理由道歉:但如果问题不清楚,你就是失去获得答案的机会的人:)。尝试一些东西,让我知道是否可以将其添加为答案(带有额外的解释)。将
r.Permissions.Company/p.User.Permissions.Company投影到您的匿名类型投影中(在您的新 {} 内)
标签: c# asp.net sql linq entity-framework