从DocumentDB查询POCO实体 [英] Querying POCO Entities from DocumentDB
问题描述
我下面从这个博客帖子微软测试出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用户$ C $的具体实例C>将返回所有文件,无论类型。
在默认情况下,所有的属性都编入索引,包括您的新成立的键入
属性,它可以让你无需收集扫描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屋!