请注意,本站并不支持低于IE8的浏览器,为了获得最佳效果,请下载最新的浏览器,推荐下载 Chrome浏览器
欢迎光临。交流群:166852192

yessql


介绍

本教程的目的是了解如何将一些自定义对象保存到文档存储,创建一些索引并执行一些查询。这假设您对C#有一些很好的了解,并且熟悉文档数据库概念。
该教程的完整来源可以在samples目录的源代码中找到:https//github.com/sebastienros/yessql/tree/master/samples/YesSql.Samples.Hi
模型
本教程中将使用的模型由单个类“BlogPost”组成。这是完整的课程:
public class BlogPost
    {        public string Title { get; set; }  
          public string Author { get; set; }        
          public string Content { get; set; }       
           public DateTime PublishedUtc { get; set; }  
                 public string[] Tags { get; set; }
    }
该类包含不同的内容类型,以证明我们在建模过程中不必关心它们。对他们没有约束。作为一个文档,它是一个根聚合,这意味着任何相关对象将被持久化为一个文档。YesSql中,文档将作为表中的单个数据库记录实现Document

配置存储

存储只是一个简单的关系数据库实例。它可以是任何类型的SQL数据库,只要[Dapper](https://github.com/StackExchange/dapper-dot-net)支持它。本教程将使用Microsoft Sql Ce 4.0,但您可以将其切换到所需的任何人。
存储由Store代理一个应用程序Store应该是唯一的,一个单例。这是数据库管理中的常见做法。如果您曾经使用像NHibernate或Entity Framework这样的ORM,那么它将会很熟悉。这取决于每个应用程序来定义什么策略用于访问此单例(DI,静态访问器,...)。本教程基于单一方法调用,这意味着它不会处理此特定方面。

var configuration = new Configuration
    {
        ConnectionFactory = new DbConnectionFactory<SqliteConnection>(@"Data Source=yessql.db;Cache=Shared", true),
        DocumentStorageFactory = new new SqlDocumentStorageFactory()
    };    // Create a reusable store holding the configuration
    var store = new Store(configuration);    
    // Creates the necessary tables
    store.InitializeAsync().Wait();
在此示例中,使用连接字符串初始化该存储,该连接字符串命名为本地Sqlite数据库yessql.db
在这个阶段你显然需要添加一个参考,Microsoft.Data.Sqlite如果你想运行应用程序。

持久化数据

该商店将作为数据库事务的工厂。在YesSql中,它们被称为__sessions__。

    //创建一个博客文章
    // creating a blog post
    var post = new BlogPost
    {
        Title = "Hello YesSql",
        Author = "Bill",
        Content = "Hello",
        PublishedUtc = DateTime.UtcNow,
        Tags = new[] {"Hello", "YesSql"}
    };    // saving the post to the database
    using(var session = store.CreateSession())
    {        session.Save(post);
    }
处理会话后,所有更改将自动刷新到数据库。或者,如果要处理将更改刷新到数据库时可以显式使用session.CommitAsync(),即使事务处理完毕后实际上将提交事务。session.Cancel()可以使用调用来阻止当前更改被提交。
读取数据
现在文档已被保存在商店中,我们可能需要检索它。它可以以各种方式完成,这些方法都将被探索,但最简单的方法是仅通过其类型加载文档。
    // 
    using(var session = store.CreateSession())
    {        
    var p = session.Query<BlogPost>().FirstOrDefault();        
    Console.WriteLine(p.Title); // > Hello YesSql
    }

更新数据

更新文档并将其保存回存储应作为同一会话的一部分进行。

    // 
   using(var session = store.CreateSession())
    {        var p = session.Query<BlogPost>().FirstOrDefault();     
       // this change will be saved back into the same store document
        p.Title = "A new title";
    }
使用该Query方法不能访问文档本身的内部属性,这是大多数真实场景的主要限制。要进行此类查询,您将需要创建一些专用索引。

查询数据

在YesSql中,查询是在称为索引的物化视图上执行的。有两种类型的索引:

  • 映射索引,对文档属性进行基本查询
  • 减少索引,用于对聚合属性值进行分组和查询

创建映射索引

映射的索引表示为继承自“MapIndex”的类。这是一个例子,它将存储`BlogPost`类的`Author`属性。

    public class BlogPostByAuthor : MapIndex
    {        public string Author { get; set; }
    }

声明地图逻辑

索引必须在`IIndexProvider`实现中描述。这是通过继承“IndexProvider”来注册“BlogPostByAuthor”。

   public class BlogPostIndexProvider : IndexProvider<BlogPost>
    {        public override void Describe(DescribeContext<BlogPost> context)
        {            // for each BlogPost, create a BlogPostByAuthor index
            context.For<BlogPostByAuthor>().Map(blogPost => new BlogPostByAuthor { Author = blogPost.Author });
        }
    }
该类将告诉系统如何从现有BlogPost对象构造索引现在只有一个索引被定义,但是几个可以在同一个提供者中描述。
然后提供者在系统中注册:
store.RegisterIndexes<BlogPostIndexProvider>();

使用地图索引来查询文档

查询直接在地图索引上执行。您可以使用`QueryIndex()'查询索引本身,或者在“ISession”实例上查询“QueryByMappedIndex()”来检索相关联的文档。```csharp //由作者使用(var session = store.CreateSession())加载博客帖子{var ps = await session.QueryAsync(x => x.Author.StartsWith(“B”))。

    foreach (var p in ps)
    {
        Console.WriteLine(p.Author); // > Bill
    }}

此示例演示如何使用查询 '博客' 他们 '作者' 属性的索引。
使用 map/reduce indexes
map/reduce 索引是非常有用来构建从多个对象的聚合的信息。
与地图索引,一个索引条目与只有一个对象相关,而map/reduce ,
索引条目将代表一组对象的某些信息。
创建一个 map/reduce 索引
我们想要计算特定的一天,发表了一些指标代表多少 '博客 '
和也留下一丝痕迹的这些职位。这里是 'BlogPostByDay' 索引类继承 'ReduceIndex'.' '
    public class BlogPostByDay : ReduceIndex
    {
        public virtual string Day { get; set; }
        public virtual int Count { get; set; }
    }

该索引然后需要在索引提供程序中进行描述。唯一的区别是,除了地图功能之外,还需要定义如何分组,还可以减少这些结果。最终删除功能告诉YesSql在相关对象被删除时与索引有什么关系,与减少索引相反

context.For<BlogPostByDay, string>()
        .Map( blogPost => new BlogPostByDay {
                    Day = blogPost.PublishedUtc.ToString("yyyyMMdd"),
                    Count = 1
            })
        .Group( blogPost => blogPost.Day )
        .Reduce( group => new BlogPostByDay {
                Day = group.Key,
                Count = group.Sum(p => p.Count)
            })
        .Delete( (index, map) => {
                index.Count -= map.Sum(x => x.Count);                
                // if Count == 0 then delete the index
                return index.Count > 0 ? index : null;
            });

使用map / reduce索引来查询文档

以下是使用新创建的索引的一些示例:

    // 
    using (var session = store.CreateSession())
    {       
    var ps = await session.QueryAsync<BlogPost, BlogPostByDay>(x => x.Day == DateTime.UtcNow.ToString("yyyyMMdd")).List();       
     foreach (var p in ps)
        {
            Console.WriteLine(p.PublishedUtc); // > [Now]
        }
    }    // counting blog posts by day
    using (var session = store.CreateSession())
    {        var days = await session.QueryIndexAsync<BlogPostByDay>().ToList();        
    foreach (var day in days)
        {
            Console.WriteLine(day.Day + ": " + day.Count); // > [Today]: 1
        }
    }



作者原创内容不容易,如果觉得内容不错,请点击右侧“打赏”,赏俩给作者花花,也算是对作者付出的肯定,也可以鼓励作者原创更多更好内容。
更多详情欢迎到QQ群 166852192 交流。