我有4张桌子:
但是当我创建实体框架模型时,为什么tblRoleInProfile
没有生成?
我有一个想要将其转换为EF的Linq TO SQL模型,现在我的表格没有生成。我该如何解决?
更新1:
您认为我们有一些个人资料和一些角色。如果我们希望配置文件A具有角色1在tblRoleInProperty
中插入记录,如果我们希望配置文件B没有角色2(如果存在),则从tblRoleInProperty
删除它的记录。我不想删除个人资料。另一个问题是选择新投影。任何机构都可以指导我在EF中写这个查询:
var prs = from p in dc.tblProfiles
join rp in dc.tblRoleInProfiles
on p.ProfileId equals rp.ProfileId
join r in dc.tblRoles
on rp.RoleId equals r.RoleId
select new
{
ProfileName = p.ProfileName,
ProfileId = p.ProfileId,
RoleName = r.RoleName,
RoleId = r.RoleId
};
由于
答案 0 :(得分:6)
这就是EF的工作原理。 EF是ORM工具 - 它试图隐藏持久性细节,并且多对多关系中的联结表正是您不希望在对象模型中看到的细节。
您可以将查询重写为:
var prs = from p in dc.tblProfiles
from r in p.tblRoles
select new
{
ProfileName = p.ProfileName,
ProfileId = p.ProfileId,
RoleName = r.RoleName,
RoleId = r.RoleId
};
更新和删除关系也适用于导航属性。
将角色插入个人资料:
// Dummy objects so you do not need to load them from DB first.
// These objects must exist in database
var p = new Profile { ProfileId = ... };
var r = new Role { RoleId = ... };
context.tblProfiles.Attach(p);
context.tblRoles.Attach(r);
p.tblRoles.Add(r);
context.SaveChanges();
从个人资料中删除角色:
// Dummy objects so you do not need to load them from DB first.
// These objects must exist in database
var p = new Profile { ProfileId = ... };
var r = new Role { RoleId = ... };
p.tblRoles.Add(r);
context.tblProfiles.Attach(p);
context.tblRoles.Attach(r);
p.tblRoles.Remove(r);
// another approach:
// context.ObjectStateManager.ChangeRelationshipState(p, r, x => x.tblRoles, EntityState.Deleted);
context.SaveChanges();
答案 1 :(得分:2)
但是当我创建一个实体框架时 model为什么tblRoleInProfile没有 产生
实体框架正确识别了表示tblProfile
和tblRole
之间纯粹的多对多关系的表格。现在通过这两个表中的导航属性表达此关系。当您访问导航属性时,EF将在内部为您执行连接以返回正确的相关实体 - 最终这将导致更清晰的查询,因为您不再需要明确表达连接。
至于你的例子,我会重新考虑你的表/实体上的tbl前缀 - 它真的会伤害你的可读性。
答案 2 :(得分:1)
您可以更改表以保留额外的ID列而不是超级键。我知道这不是必要的,但EF肯定会导入它。
答案 3 :(得分:1)
一般来说,你不应该做任何事情。您的实体是角色和个人资料。您想要使用实体之间创建的关系。
var db = new Entities(); //whatever your context name is
var r = new Role{RoleName="Rtest"};
var p = new Profile {ProfileName = "PTest"};
p.Roles.Add(r);
db.Profiles.AddObject(p);
db.SaveChanges();
EF将负责其余部分。我知道你在L2S上投入了大量的工作,但如果你遵循EF快乐路径并做出一些改变而不是强迫EF看起来像LINQ to SQL,你可能会发现你的生活更轻松。
您可以这样查询:
var qu = from r in dc.tblRoles
where r.tblProfiles.Any(p=> p.ProfileId == 42)
select r;
foreach (var r in qu) {
Console.WriteLine(r.RoleName)
foreach (var p in r.tblProfiles) {
Console.WriteLine(p.ProfileName)
}
}
答案 4 :(得分:0)
我的解决方案是在关系表中插入一列:
tblRoleInProfile (
ProfileId int not null,
RoleId int not null,
UpdateDate DateTime not null
)...
在我的情况下实际上并不需要该列,但它可以达到目的