Entity Framework не импортирует таблицу с супер ключом - PullRequest
2 голосов
/ 03 апреля 2011

У меня есть 4 таблицы:

, но когда я создаю модель платформы сущностей, почему tblRoleInProfile не генерируется?

enter image description here

У меня есть модель Linq TO SQL, которая хочет преобразовать ее в EF, и теперь моя таблица не генерируется.Как я могу решить это?

ОБНОВЛЕНИЕ 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 ]

6 голосов
/ 03 апреля 2011

Так работает 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();
2 голосов
/ 03 апреля 2011

но когда я создаю структуру сущности модель Почему tblRoleInProfile нет генерируется

Платформа Entity Framework правильно определила таблицу, представляющую чистое отношение «многие ко многим» между tblProfile и tblRole. Эта связь теперь выражается через свойства навигации в этих двух таблицах. Когда вы получаете доступ к свойству навигации, EF выполнит для вас внутреннее объединение, чтобы вернуть вам нужные связанные сущности - в конце это приведет к гораздо более чистым запросам, поскольку вам больше не нужно явно выражать объединение.

Что касается вашего примера, я бы пересмотрел префикс tbl для ваших таблиц / сущностей - это действительно ухудшает читабельность.

1 голос
/ 03 апреля 2011

В общем, вы не должны ничего делать.Ваши лица Роль и Профиль.Вы хотели бы использовать отношения, созданные между сущностями.

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)
   }
 }
1 голос
/ 03 апреля 2011

Вы можете изменить свою таблицу, чтобы она содержала дополнительный столбец идентификатора вместо суперключа.Я знаю, что это не обязательно, но таким образом EF обязательно импортирует его.

0 голосов
/ 09 марта 2017

Мое решение заключалось в том, чтобы вставить столбец в таблицу отношений:

tblRoleInProfile (
    ProfileId int not null,
    RoleId int not null,
    UpdateDate DateTime not null
)...

в моем случае столбец не нужен, но он служит цели

...