2

I need some help on a sql query, for which I am using EntityFramework as ORM.

I have a User-- Group Many to Many relationship, i.e one user can belong to more than one group and one group can have more than 1 user.

The way I have done the mapping is..

USER tbl, Usr_Grp table, and Group Table where PK = Primary Key, FK = Foreign Key

USER table has --> UserId(PK) , UserName
Group table has --> GroupId (PK), GroupName
Usr_Grp table has --> Id(PK), UUserId(FK to usertable), GGroupId (FK to GroupTable)

The issue that I am facing is... In my api , I will get a set of GroupId's and I want to find only those Users that belong to all these GroupId's ( i.e all the groups that are passes in).

Is there a way to write this query in entity framework or Sql. I would really appreciate any help I can get on this.

-RN

4
  • I'm not very familiar with Entity Framework, but would the sql query help that I would execute? Commented Dec 18, 2010 at 6:34
  • Yep that would definetly help. Commented Dec 18, 2010 at 6:35
  • Please have a look : stackoverflow.com/questions/553918/… Commented Dec 18, 2010 at 6:36
  • @adatapost That question is little different, I have a set of roles that the user has to belong to. I am not having issues with EF, I can figure that out but I am not able to get the Correct SQL query. Commented Dec 18, 2010 at 6:41

3 Answers 3

6

Junction table Usr_Grp shouldn't have Id. If you create complex primary key over (UUserId, GGroupId), then EF automatically would understand, that it is Many-To-Many relation.

If you make your relations as follows:alt text

Then EF will generate entities with Many-To-Many relations:alt text

After you have everything set up you can easily use such code:

var ids = new List<int>{1, 2, 3, 4}; // GroupIds you need
context.Groups
        .Where(x=> ids.Contains(x.Id))
        .SelectMany(x=>x.Users)
        .Distinct()
        .ToArray();

If you cannot change model, then just use such linq query:

context.Grp_Usrs
        .Where(x=> ids.Contains(x.GroupId))
        .SelectMany(x=>x.Users)
        .Distinct()
        .ToArray();
Sign up to request clarification or add additional context in comments.

4 Comments

Isn't it possible to simply remove the Usr_Grp entity, and then use it to form a many-many relationship between the two tables, without removing the Id column? I know EF won't do it if you just drag the table onto the designer, but can't you manually do it?
@Kirk Broadhurst - Never tried to do such a thing. I don't like editing edmx file manually. I suppose it's not possible, but it is nothing, but my feelings. I really could be wrong. You can ask this as separate question on stackoverflow, cleaver people could answer.
@ Ben - see last lines of answer if you cannot change model. It's not as clear as Many-To-Many relation, but it should work.
I'm not suggesting editing the edmx, but just right click on the designer and add a new relationship between the two tables.
0

Try this method:

var gid = new List<int> {1, 2, 3, 4};
var users_id = entity.Usr_Grp.where(x=> gid.Contains(x.uid);

Hope it helps!

Comments

0
    //Here is a LinqToSql example but it should work with EF too.Taking into consideration your mappings I would have the following approach in handling a many to many relationship:

    //1. First You need to save you records into the tables as many to many relationship
    [Test]
    public void CanSaveGroupUsers()
    {
        var group = Group { CreatedDate = DateTime.UtcNow, Name = "The Rookies" };
        var groupId = _groupRepository.SaveGroup(group);

        var user = new User { CreatedDate = DateTime.Now, Name = "Justin Bieber" };
        var userId = _userRepository.SaveUser(user);

        var userGroup = new UserGroup { GroupId = groupId, UserId = userId };
        _group.SaveUserGroup(userGroup);
    }

    //2. Then you can retrive them this way:
    [Test]
    public void CanGetGroupUsers()
    {
        var groupIds = new List<int>{1,2,3,4};
        var users = _usersRepository.GetAllUsers();
        var specificUsersList = (users.AsQueryable().Where(user => groupIds.Contains(user.UserGroups.FirstOrDefault().GroupId)));
    }

    //3. I attached my repository code just in case
    public IQueryable<User> GetAllUsers()
    {
        _db.ObjectTrackingEnabled = false;
        return _db.Users;
    }
    public int SaveGroup(Group Group)
    {
        var dbGroup = new Group
        {
            Name = Group.Name,
            CreatedDate = Group.CreatedDate
        };
        _db.Groups.InsertOnSubmit(dbGroup);
        _db.SubmitChanges();
        return dbGroup.Id;
    }

    public int SavUser(User user)
    {
        var dbUser = new User
        {
            CreatedDate = user.CreatedDate,
            Name = user.Name
        };
        _db.Users.InsertOnSubmit(dbUser);
        _db.SubmitChanges();
        return dbUser.UserId;
    }

     public void SaveUserGroup(UserGroup userGroup)
    {
        var dbUserGroup = new UserGroup
        {
            GroupId = userGroup.GroupId,
            UserId = userGroup.UserId

        };
        _db.UserGroups.InsertOnSubmit(dbUserGroup);
        _db.SubmitChanges();
    }

    //Hope this helps:)

2 Comments

EntityFramework will abstract the UserGroup table away into a pure relationship - so that User has a Groups property, and Group has a Users property. The UserGroup table won't appear in the generated namespace as an entity at all.
Thanks for pointing this out. I usually use NHibernate where you also don't need the third table(GroupUsers) as you can specify the the manytomany mappings and you only need the users and group entities. Looks like is time for me to move from LinqToSql to EF :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.