2011-12-08 3 views
1

J'ai collection de documents Les utilisateursrequête RavenDB ne contient pas

User 
{ 
    "Status": "ACTIVE", 
    "Login": { 
    "UserName": "login", 
    "Password": null, 
    "CreationDate": "2011-12-07T11:30:24.4062500Z", 
    "Roles": [ 
     { 
     "Id": "roles/WebUser", 
     "Name": "WebUser" 
     }, 
     { 
     "Id": "roles/Admin", 
     "Name": "Admin" 
     } 
    ] 
    }, 
} 

Comment puis-je faire une requête pour obtenir la liste des utilisateurs avec un nom de rôle « WebUser » sauf les utilisateurs avec le nom de rôle « Admin » (CONTIENT rôle « WebUser "mais contient rôle "admin")

LINQ ou Lucene

Répondre

2

Vous devez créer un index pour cela, quelque chose comme:

from user in docs.Users 
select new { Roles = user.Logins.Roles.Select(x=>x.Name) } 

Et vous pouvez interroger utilise:

Roles:WebMaster AND -Roles:Admin 
+0

Merci. Cela fonctionne avec un petit ajustement: à partir de doc dans docs.Users select new {RoleName = ((IEnumerable ) doc.Login.Roles) .Select (x => x.Name) – Alfer

+0

Vous ne savez pas si cette syntaxe est archaïque mais le '-' n'a pas fonctionné pour moi. J'ai fini par devoir utiliser 'NOT Prop: Value' mais cela n'a pas suffi, j'ai dû ajouter le hack' *: * AND NOT Prop: Value' qui, j'en suis sûr, a des problèmes de performances. Est-ce que je manque quelque chose? –

1

Est-ce que vous voulez?

unité d'échantillonnage
var users = documentSession.Query<User>() 
    .Where(x => x.Login.Roles.Any(y => y.Name == "WebUser")) 
    .Where(x => x.Login.Roles.Any(y => y.Name != "Admin")) 
    .ToList(); 

essai ....

using System; 
using System.Collections.Generic; 
using System.Linq; 
using NUnit.Framework; 
using Raven.Client; 
using Raven.Client.Embedded; 
using Raven.Client.Linq; 

namespace Foo.Tests. 
{ 
    public class UserTests 
    { 
     [Test] 
     // ReSharper disable InconsistentNaming 
     public void GivenSomeUsersWithWebUserAndAdminRoles_Query_ReturnsSomeUsers() 
     // ReSharper restore InconsistentNaming 
     { 
      IDocumentStore documentStore; 
      using (documentStore = new EmbeddableDocumentStore {RunInMemory = true}) 
      { 
       // Arrange. 
       documentStore.Initialize(); 

       // Create and store Fake Data. 
       using (IDocumentSession documentSession = documentStore.OpenSession()) 
       { 
        IEnumerable<User> users = CreateFakeUsers(documentSession); 
        foreach (var user in users) 
        { 
         documentSession.Store(user); 
        } 
        documentSession.SaveChanges(); 
       } 

       using (IDocumentSession documentSession = documentStore.OpenSession()) 
       { 
        // Act. 
        var users = documentSession.Query<User>() 
         .Where(x => x.Login.Roles.Any(y => y.Name == "WebUser")) 
         .Where(x => x.Login.Roles.Any(y => y.Name != "Admin")) 
         .ToList(); 

        // Assert. 
        Assert.IsNotNull(users); 
        Assert.AreEqual(2, users.Count); 
       } 
      } 
     } 

     private IEnumerable<User> CreateFakeUsers(IDocumentSession documentSession) 
     { 
      return new List<User> 
         { 
          new User 
           { 
            Status = "ACTIVE", 
            Login = new Login 
               { 
                UserName = "loging", 
                Password = null, 
                CreationDate = DateTime.UtcNow, 
                Roles = new List<Role> 
                   { 
                    new Role 
                     { 
                      Id = "roles/WebUser", 
                      Name = "WebUser" 
                     }, 
                    new Role 
                     { 
                      Id = "roles/Admin", 
                      Name = "Admin" 
                     } 
                   } 
               } 
           }, 
          new User 
           { 
            Status = "ACTIVE", 
            Login = new Login 
               { 
                UserName = "User 2", 
                Password = null, 
                CreationDate = DateTime.UtcNow, 
                Roles = new List<Role> 
                   { 
                    new Role 
                     { 
                      Id = "roles/WebUser", 
                      Name = "WebUser" 
                     } 
                   } 
               } 
           }, 
          new User 
           { 
            Status = "INACTIVE", 
            Login = new Login 
               { 
                UserName = "User 3", 
                Password = null, 
                CreationDate = DateTime.UtcNow, 
                Roles = new List<Role> 
                   { 
                    new Role 
                     { 
                      Id = "roles/Admin", 
                      Name = "Admin" 
                     } 
                   } 
               } 
           } 
         }; 
     } 

     #region Nested type: Login 

     private class Login 
     { 
      public string UserName { get; set; } 
      public string Password { get; set; } 
      public DateTime CreationDate { get; set; } 
      public ICollection<Role> Roles { get; set; } 
     } 

     #endregion 

     #region Nested type: Role 

     private class Role 
     { 
      public string Id { get; set; } 
      public string Name { get; set; } 
     } 

     #endregion 

     #region Nested type: User 

     private class User 
     { 
      public string Id { get; set; } 
      public string Status { get; set; } 
      public Login Login { get; set; } 
     } 

     #endregion 
    } 
} 
+0

Non. Utilisateurs du rôle "WebUser" mais pas du rôle "Admin" (Non t contient le rôle "Admin") est ce que je veux. Dans votre exemple, il est seulement le deuxième utilisateur – Alfer