我有一个具有角色的实体用户,我需要使用我们的角色(但不是代理对象)加载用户。
class User{
public int Id{get; set;}
public string Name{get; set;}
public ICollection<Role> Roles{get; set;}
}
class Role{
public int Id{get; set;}
public string Name{get; set;}
public virtual User User{get; set;}
}
当我使用它时:DbContext.Users.Where(x => x.Id == id).Include(x => x.Roles).FirstOrDefault()
我获得了具有角色代理对象的User对象。
我需要具有Role对象的User对象。 怎么做?感谢
答案 0 :(得分:1)
回答您的具体答案,只需针对特定代码块禁用代理创建,但您必须急切加载您的实体,如下所示:
public static IEnumerable<IEnumerable<T>> GetKCombs<T>(IEnumerable<T> list, int length) where T : IComparable
{
if (length == 1)
{
return list.Select(t => new T[] { t });
}
else
{
return GetKCombs(list, length - 1).SelectMany(t => list.Where(o => o.CompareTo(t.Last()) > 0), (t1, t2) => t1.Concat(new T[] { t2 }));
}
}
...这将仅影响该实例。我将它包装在try finally块中,因为如果在加载实体时发生任何异常,您可以确保该选项将被反转。
你也可以在try
{
DbContext.Configuration.ProxyCreationEnabled = false;
var userWithRoles = DbContext.Users.Include(x => x.Roles).Where(x => x.Id == id).FirstOrDefault();
}
finally
{
DbContext.Configuration.ProxyCreationEnabled = true;
}
构造函数中全局设置它,但我不推荐这个:
DbContext
我的建议是避免将数据库实体暴露给API。您可以创建DTO类并公开它们,而不是:
public class YourDbContext : DbContext
{
public YourDbContext() : base("name=ConnectionString")
{
this.Configuration.ProxyCreationEnabled = true;
}
}
然后你可以只返回DTO。像// original entities
public class User {
public int Id{get; set;}
public string Name{get; set;}
public ICollection<Role> Roles{get; set;}
// other fields like birthdate, status, password, etc...
}
public class Role {
public int Id{get; set;}
public string Name{get; set;}
public virtual User User{get; set;}
}
// DTO classes, keeping only the fields you want
// original entities
public class UserDTO {
public int Id{get; set;}
public string Name{get; set;}
public ICollection<RoleDTO> Roles{get; set;}
}
public class RoleDTO {
public int Id{get; set;}
public string Name{get; set;}
}
// project them like this:
var userDTO = DbContext.Users.Where(x => x.Id == id)
.Select(u => new UserDTO
{
Id = u.Id,
Name = u.Name,
Roles = u.Roles.Select(r => new RoleDTO
{
Id = r.Id,
Name = r.Name
}),
})
.FirstOrDefault();
这样的工具可以让投影DTO课程更简单,更清晰,这只是一个例子。