实体框架不会使用超级密钥导入表

时间:2011-04-03 04:13:43

标签: c# entity-framework entity-framework-4 linq-to-entities many-to-many

我有4张桌子:

但是当我创建实体框架模型时,为什么tblRoleInProfile没有生成?

enter image description here

我有一个想要将其转换为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
          };

由于

5 个答案:

答案 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没有   产生

实体框架正确识别了表示tblProfiletblRole之间纯粹的多对多关系的表格。现在通过这两个表中的导航属性表达此关系。当您访问导航属性时,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
)...

在我的情况下实际上并不需要该列,但它可以达到目的