从DocumentDB查询POCO实体 [英] Querying POCO Entities from DocumentDB

查看:153
本文介绍了从DocumentDB查询POCO实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我下面从这个博客帖子微软测试出DocumentDB。

我创建了一个集合,并通过不同的POCO类在我的应用程序插入2个文档。它创建的文档,但我不能将它们过滤回各自的POCO类。我意识到,我查询所有集合所以它显然是获取存储在集合中的所有文件。

什么是差异化,而查询文件,这样我可以按类型分别查询它们的最好方法?

我可以一个类型字段添加到文档,并可以通过其中type =用户,但我不知道我能不能做 SELECT * FROM用户与用户是一个文档类型(如果在DocumentDB这样的事情),而不是一个集合。

这里是我如何创建文档:

  VAR USER1 =新用户()
    {
        UserTypeId = 0,
        用户名=user1@hotmail.com
        密码=12345,
        PasswordSalt =saltyPassword
        UserStatusId = 1,
        ProfilePhotoKey =KJSY
    };
    等待DocumentDBRepository<使用者> .CreateItemAsync(用户1);    VAR的客户=新客户()
    {
        CLIENTNAME =CLIENT1
        揭秘=​​rxPBsIVYya2Jg2ZHPNG8gL0P36TnutiBehvEFgk938M =,
        标题=管理前端应用
        ApplicationTypeId = 0,
        活动=假,
        RefreshTokenLifeTime = 60,
        AllowedOrigin =HTTP://本地主机:8080
        AllowedRoles =管理员
    };
    等待DocumentDBRepository<客户> .CreateItemAsync(客户端);

文件DB信息库类

 公共静态类DocumentDBRepository< T>
{
    //使用数据库,如果它存在,如果不创建一个新的数据库
    私有静态数据库ReadOrCreateDatabase()
    {
        变种DB = Client.CreateDatabaseQuery()
                        。凡(D => d.Id == DatabaseId)
                        .AsEnumerable()
                        .FirstOrDefault();        如果(DB == NULL)
        {
            DB = Client.CreateDatabaseAsync(新数据库{ID = DatabaseId})结果。
        }        返回分贝;
    }    //使用DocumentCollection如果存在的话,如果不创建一个新的集合
    私有静态DocumentCollection ReadOrCreateCollection(字符串databaseLink)
    {
        VAR COL = Client.CreateDocumentCollectionQuery(databaseLink)
                          。凡(C => c.Id == CollectionId)
                          .AsEnumerable()
                          .FirstOrDefault();        如果(COL == NULL)
        {
            VAR collectionSpec =新DocumentCollection {ID = CollectionId};
            VAR requestOptions =新RequestOptions {OfferType =S1};            COL = Client.CreateDocumentCollectionAsync(databaseLink,collectionSpec,requestOptions)。结果;
        }        返回关口;
    }    //从暴露配置中数据库值作为内部使用的属性
    私人静态字符串databaseId;
    私人静态字符串DatabaseId
    {
        得到
        {
            如果(string.IsNullOrEmpty(databaseId))
            {
                databaseId = ConfigurationManager.AppSettings [数据库];
            }            返回databaseId;
        }
    }    //从暴露配置中收藏价值作为内部使用的属性
    私人静态字符串collectionId;
    私人静态字符串CollectionId
    {
        得到
        {
            如果(string.IsNullOrEmpty(collectionId))
            {
                collectionId = ConfigurationManager.AppSettings [收藏];
            }            返回collectionId;
        }
    }    //使用ReadOrCreateDatabase函数获取到该数据库的引用。
    私有静态数据库数据库;
    私有静态数据库数据库
    {
        得到
        {
            如果(数据库== NULL)
            {
                数据库= ReadOrCreateDatabase();
            }            返回数据库;
        }
    }    //使用ReadOrCreateCollection函数来获取到集合的引用。
    私有静态DocumentCollection收集;
    私有静态DocumentCollection收藏
    {
        得到
        {
            如果(收集== NULL)
            {
                集合= ReadOrCreateCollection(Database.SelfLink);
            }            返回集合;
        }
    }    //这个属性建立一个新的连接到DocumentDB第一次使用它,
    //然后再次使用该实例为应用避免的持续时间
    //实例DocumentClient的一个新实例,每个请求的开销
    私有静态DocumentClient客户端;
    私有静态DocumentClient客户端
    {
        得到
        {
            //改变政策ConnectionMode:直接和ConnectionProtocol:TCP上的发布到AZURE
            如果(客户端== NULL)
            {
                弦端点= ConfigurationManager.AppSettings [端点];
                字符串AUTHKEY = ConfigurationManager.AppSettings [AUTHKEY];
                乌里endpointUri =新的URI(终点);
                客户端=新DocumentClient(endpointUri,AUTHKEY);
            }            返回客户端;
        }
    }
    / *查询助手* /
    公共静态的IEnumerable< T> GetAllItems()
    {
        返回Client.CreateDocumentQuery< T>(Collection.DocumentsLink)
            .AsEnumerable();
    }
    公共静态的IEnumerable< T> GetItems(前pression<&Func键LT; T,BOOL>> predicate)
    {
        返回Client.CreateDocumentQuery< T>(Collection.DocumentsLink)
            。凡(predicate)
            .AsEnumerable();
    }
    公共静态异步任务<文件> CreateItemAsync(T项)
    {
        返回等待Client.CreateDocumentAsync(Collection.SelfLink,项目);
    }
    公共静态ŧ的GetItem(前pression<&Func键LT; T,BOOL>> predicate)
    {
        返回Client.CreateDocumentQuery< T>(Collection.DocumentsLink)
                    。凡(predicate)
                    .AsEnumerable()
                    .FirstOrDefault();
    }    公共静态异步任务<文件> UpdateItemAsync(字符串ID,T项)
    {
        文档的文档= GetDocument(ID);
        返回等待Client.ReplaceDocumentAsync(doc.SelfLink,项目);
    }    私有静态文档GetDocument(字符串ID)
    {
        返回Client.CreateDocumentQuery(Collection.DocumentsLink)
            。凡(D => d.Id == ID)
            .AsEnumerable()
            .FirstOrDefault();
    }
}

我想获得:

 变种Q = DocumentDBRepository<使用者> .GetAllItems()了ToList()。
    VAR T = DocumentDBRepository<客户> .GetAllItems()了ToList()。

问:应该包含那些被

创建的用户文件

 等待DocumentDBRepository<使用者> .CreateItemAsync(用户1);

和那些被

创建T应当只包含客户端记录

 等待DocumentDBRepository<客户> .CreateItemAsync(客户端1);


解决方案

由于DocumentDB没有任何内置的键入元数据每个文件,你需要添加一个(如键入属性,你的建议,或任何其他区别的属性)存储相同集合中的异构文档时,在你的 WHERE 条款。你的名字是什么这个属性,什么值,你把它存储,什么都没有做与你的集合名称。

关于你的 SELECT * FROM用户WHERE类型='用户'将工作,但 SELECT * FROM用户将返回所有文件,无论类型。

在默认情况下,所有的属性都编入索引,包括您的新成立的键入属性,它可以让你无需收集扫描efficently执行您的WHERE子句的过滤。

I am following this blog post from Microsoft testing out DocumentDB.

I have created a collection and inserted 2 documents via different POCO classes on my application. It created the documents but I cannot filter them back into their respective POCO classes. I realized that I am querying all the collection so it is obviously retrieving all the documents stored inside that collection.

What is the best way to differentiate documents while querying so that I can query them separately by type?

I can add a type field to the document and can get by WHERE type="user" but I'm not sure that I cannot do SELECT * FROM users with users being a document type (if there is such a thing in DocumentDB), not a collection.

Here is how I am creating documents:

    var user1= new User()
    {
        UserTypeId = 0,
        UserName = "user1@hotmail.com",
        Password = "12345",
        PasswordSalt = "saltyPassword",
        UserStatusId = 1,
        ProfilePhotoKey = "KJSY"
    };
    await DocumentDBRepository<User>.CreateItemAsync(user1);

    var client = new Client()
    {
        ClientName = "client1",
        Secret = "rxPBsIVYya2Jg2ZHPNG8gL0P36TnutiBehvEFgk938M=",
        Title = "Administration Front End Application",
        ApplicationTypeId = 0,
        Active = false,
        RefreshTokenLifeTime = 60,
        AllowedOrigin = "http://localhost:8080",
        AllowedRoles = "admin"
    };
    await DocumentDBRepository<Client>.CreateItemAsync(client);

Document Db repository class

public static class DocumentDBRepository<T>
{
    //Use the Database if it exists, if not create a new Database
    private static Database ReadOrCreateDatabase()
    {
        var db = Client.CreateDatabaseQuery()
                        .Where(d => d.Id == DatabaseId)
                        .AsEnumerable()
                        .FirstOrDefault();

        if (db == null)
        {
            db = Client.CreateDatabaseAsync(new Database { Id = DatabaseId }).Result;
        }

        return db;
    }

    //Use the DocumentCollection if it exists, if not create a new Collection
    private static DocumentCollection ReadOrCreateCollection(string databaseLink)
    {
        var col = Client.CreateDocumentCollectionQuery(databaseLink)
                          .Where(c => c.Id == CollectionId)
                          .AsEnumerable()
                          .FirstOrDefault();

        if (col == null)
        {
            var collectionSpec = new DocumentCollection { Id = CollectionId };
            var requestOptions = new RequestOptions { OfferType = "S1" };

            col = Client.CreateDocumentCollectionAsync(databaseLink, collectionSpec, requestOptions).Result;
        }

        return col;
    }

    //Expose the "database" value from configuration as a property for internal use
    private static string databaseId;
    private static String DatabaseId
    {
        get
        {
            if (string.IsNullOrEmpty(databaseId))
            {
                databaseId = ConfigurationManager.AppSettings["database"];
            }

            return databaseId;
        }
    }

    //Expose the "collection" value from configuration as a property for internal use
    private static string collectionId;
    private static String CollectionId
    {
        get
        {
            if (string.IsNullOrEmpty(collectionId))
            {
                collectionId = ConfigurationManager.AppSettings["collection"];
            }

            return collectionId;
        }
    }

    //Use the ReadOrCreateDatabase function to get a reference to the database.
    private static Database database;
    private static Database Database
    {
        get
        {
            if (database == null)
            {
                database = ReadOrCreateDatabase();
            }

            return database;
        }
    }

    //Use the ReadOrCreateCollection function to get a reference to the collection.
    private static DocumentCollection collection;
    private static DocumentCollection Collection
    {
        get
        {
            if (collection == null)
            {
                collection = ReadOrCreateCollection(Database.SelfLink);
            }

            return collection;
        }
    }

    //This property establishes a new connection to DocumentDB the first time it is used, 
    //and then reuses this instance for the duration of the application avoiding the
    //overhead of instantiating a new instance of DocumentClient with each request
    private static DocumentClient client;
    private static DocumentClient Client
    {
        get
        {
            // change policy to ConnectionMode: Direct and ConnectionProtocol: TCP on publishing to AZURE
            if (client == null)
            {
                string endpoint = ConfigurationManager.AppSettings["endpoint"];
                string authKey = ConfigurationManager.AppSettings["authKey"];
                Uri endpointUri = new Uri(endpoint);
                client = new DocumentClient(endpointUri, authKey);
            }

            return client;
        }
    }


    /* QUERY HELPERS */
    public static IEnumerable<T> GetAllItems()
    {
        return Client.CreateDocumentQuery<T>(Collection.DocumentsLink)
            .AsEnumerable();
    }
    public static IEnumerable<T> GetItems(Expression<Func<T, bool>> predicate)
    {
        return Client.CreateDocumentQuery<T>(Collection.DocumentsLink)
            .Where(predicate)
            .AsEnumerable();
    }
    public static async Task<Document> CreateItemAsync(T item)
    {
        return await Client.CreateDocumentAsync(Collection.SelfLink, item);
    }
    public static T GetItem(Expression<Func<T, bool>> predicate)
    {
        return Client.CreateDocumentQuery<T>(Collection.DocumentsLink)
                    .Where(predicate)
                    .AsEnumerable()
                    .FirstOrDefault();
    }

    public static async Task<Document> UpdateItemAsync(string id, T item)
    {
        Document doc = GetDocument(id);
        return await Client.ReplaceDocumentAsync(doc.SelfLink, item);
    }

    private static Document GetDocument(string id)
    {
        return Client.CreateDocumentQuery(Collection.DocumentsLink)
            .Where(d => d.Id == id)
            .AsEnumerable()
            .FirstOrDefault();
    }
}

I am trying to get:

    var q = DocumentDBRepository<User>.GetAllItems().ToList();
    var t = DocumentDBRepository<Client>.GetAllItems().ToList();

q should contain only user documents those were created by

await DocumentDBRepository<User>.CreateItemAsync(user1);

and t should contain only client documents those were created by

await DocumentDBRepository<Client>.CreateItemAsync(client1);

解决方案

Since DocumentDB doesn't have any built-in type metadata for each document, you'd need to add one (such as the type property you suggested, or any other distinguishing property) when storing heterogeneous documents in the same collection, and use it in your WHERE clause. What you name this property, and what values you store in it, have nothing to do with your collection name.

Regarding your specific example of SELECT * from users WHERE type='user' would work, but SELECT * from users would return all documents, regardless of type.

By default, all properties are indexed, including your newly-formed type property, which lets you perform your WHERE-clause filtering efficently without requiring a collection scan.

这篇关于从DocumentDB查询POCO实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆