1. 程式人生 > 其它 >RavenDb學習(八)高階特性上半部分

RavenDb學習(八)高階特性上半部分

1、事務支援
別的關係型資料庫和RavenDb一起使用

using (var transaction = new TransactionScope())
{
    BlogPost entity = session.Load<BlogPost>("blogs/1");
 
    entity.Title = "Some new title";
 
    session.SaveChanges(); // will create HTTP request
 
    session.Delete(entity);
 
    session.SaveChanges(); // will create HTTP request
 
    transaction.Complete(); // will commit transaction
}

2、文件元資料
Raven-Clr-Type - Records the CLR type, set and used by the JSON serialization/deserialization process in the Client API.
Raven-Entity-Name - Records the entity name, aka the name of the RavenDB collection this entity belongs to.
Non-Authoritive-Information - This boolean value will be set to true if the data received by the client has been modified by an uncommitted transaction. You can read more on it in the Advanced section.
Temp-Index-Score - When querying RavenDB, this value is the Lucene score of the entity for the query that was executed.
Raven-Read-Only - This document should be considered read only and not modified.
Last-Modified - The last modified time-stamp for the entity.
@etag - Every document in RavenDB has a corresponding e-tag (entity tag) stored as a sequential Guid. This e-tag is updated by RavenDB every time the document is changed.
@id - The entity id, as extracted from the entity itself.
獲取最後修改時間的例子:
var product = session.Load<Product>(1);
RavenJObject metadata = session.Advanced.GetMetadataFor(product);
// Get the last modified time stamp, which is known to be of type DateTime
DateTime collectionName = metadata.Value<DateTime>("Last-Modified");

返回所有表的表名的map函式:
from doc in docs
where doc["@metadata"]["Raven-Entity-Name"] != null
select new { Tag = doc["@metadata"]["Raven-Entity-Name"] };

//修改元資料
1)通過session.Advanced.GetMetadatFor(entity) 獲取元資料,然後修改並儲存
2)通過documentStore.RegisterListener(myStoreListener) 註冊一個IDocumentStoreListener,當有session要進行儲存的時候,它能修改元資料

3、查詢指定列
分頁查詢某個列
var firstPage = session.Advanced.DocumentStore.DatabaseCommands.GetTerms("indexName", "MyProperty", null, 128);
var secondPage = session.Advanced.DocumentStore.DatabaseCommands.GetTerms("indexName", "MyProperty", firstPage.Last(), 128);

4、動態列

public class Product
{
    public string Id { get; set; }
    public List<Attribute> Attributes { get; set; }
}
 
public class Attribute
{
    public string Name { get; set; }
    public string Value { get; set; }
}

上述例子,一個產品有很多個屬性,屬性的型別是不固定的,需要是dynamic的

//建立索引
public class Product_ByAttribute : AbstractIndexCreationTask<Product>
{
    public Product_ByAttribute()
    {
        Map = products => from p in products
                          select new
                                     {
                                         _ = p.Attributes
                                            .Select(attribute =>
                                                CreateField(attribute.Name, attribute.Value, false, true))
                                     };
    }
}

//我們對值並不關注,只是希望呼叫CreateField方法,所以用_作為一種轉換反射。

//查詢
var products = session.Advanced.LuceneQuery<Product>("Product/ByAttribute")
    .WhereEquals("Color", "Red")
    .ToList();
這樣子它不僅僅支援字串,也支援數字等


5、自定義序列化

當RavenDb收到一個POCO的時候,它會預設把它序列化為JSON格式的資料。

1)忽略一個屬性

public class Carrot
{
    public string Id { get; set; }
 
    public decimal Length { get; set; }
 
    [JsonIgnore]
    public decimal LengthInInch
    {
        get
        {
            /* some calculations */
            return this.Length;
        }
 
        set
        {
            //...
        }
    }
}

2)序列化的時候更換名字

public class Recipe
{
    public string Id { get; set; }
 
    [JsonProperty(PropertyName = "dishes")]
    public IList<IVegetable> SideDishes { get; set; }
}

3)允許自引用
//樹形結構資料
[JsonObject(IsReference = true)]
public class Category
{
    public string Id { get; set; }
    public string Name { get; set; }
    public Category Parent { get; set; }
    public List<Category> Children { get; set; }
 
    public Category()
    {
        this.Children = new List<Category>();
    }
 
    public void Add(Category category)
    {
        category.Parent = this;
        this.Children.Add(category);
    }
}

4)自定義IContractResolver實現是序列 

store.Conventions.JsonContractResolver = new DefaultContractResolver(shareCache: true)
                                             {
                                                 DefaultMembersSearchFlags =
                                                     BindingFlags.Public | BindingFlags.Instance
                                             };