Devlooped.TableStorage 5.2.0

前缀已保留
dotnet add package Devlooped.TableStorage --version 5.2.0                
NuGet\Install-Package Devlooped.TableStorage -Version 5.2.0                
此命令旨在在 Visual Studio 的包管理器控制台中使用,因为它使用了 NuGet 模块的 Install-Package 版本。
<PackageReference Include="Devlooped.TableStorage" Version="5.2.0" />                
对于支持 PackageReference 的项目,将此 XML 节点复制到项目文件中以引用包。
paket add Devlooped.TableStorage --version 5.2.0                
#r "nuget: Devlooped.TableStorage, 5.2.0"                
#r 指令可用于 F# Interactive 和 Polyglot Notebooks。将此内容复制到交互工具或脚本的源代码中以引用包。
// Install Devlooped.TableStorage as a Cake Addin
#addin nuget:?package=Devlooped.TableStorage&version=5.2.0

// Install Devlooped.TableStorage as a Cake Tool
#tool nuget:?package=Devlooped.TableStorage&version=5.2.0                

支持 POCO 对象存储到 Azure/CosmosDB Table Storage 的仓储模式

Screenshot of basic usage

注意:此库是最新 Azure SDK v12+ 的一个非常薄的包装,并使用了 CloudStorageAccount,这是 Azure 标准库 v11 CloudStorageAccount 类的 100% 兼容实现。

用法

给定一个实体,如下:

public record Product(string Category, string Id) 
{
  public required string? Title { get; init; }
  public double Price { get; init; }
  public DateOnly CreatedAt { get; init; }
}

请注意:实体可以具有自定义构造函数,关键属性可以是只读的(例如,此例中的类别和ID),并且不需要继承任何东西,实现任何接口或使用任何自定义属性(除非你想这样做)。如上图所示,它甚至可以是简单的记录类型。

实体可以使用以下方式存储和检索:

var storageAccount = CloudStorageAccount.DevelopmentStorageAccount; // or production one
// We lay out the parameter names for clarity only.
var repo = TableRepository.Create<Product>(storageAccount, 
    tableName: "Products",
    partitionKey: p => p.Category, 
    rowKey: p => p.Id);

var product = new Product("book", "1234") 
{
  Title = "Table Storage is Cool",
  Price = 25.5,
};

// Insert or Update behavior (aka "upsert")
await repo.PutAsync(product);

// Enumerate all products in category "book"
await foreach (var p in repo.EnumerateAsync("book"))
   Console.WriteLine(p.Price);

// Query books priced in the 20-50 range, 
// project just title + price
await foreach (var info in from prod in repo.CreateQuery()
                           where prod.Price >= 20 and prod.Price <= 50
                           select new { prod.Title, prod.Price })
  Console.WriteLine($"{info.Title}: {info.Price}");

// Get previously saved product.
Product saved = await repo.GetAsync("book", "1234");

// Delete product
await repo.DeleteAsync("book", "1234");

// Can also delete passing entity
await repo.DeleteAsync(saved);

当在编译时已知实体存储布局时,也可以使用属性来消除需要使用lambda表达式。

[Table("Products")]
public record Product([PartitionKey] string Category, [RowKey] string Id) ... 

var storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
// Everything discovered from attributes.
var repo = TableRepository.Create<Product>(storageAccount);

有关如何使用它们,请参阅下文的属性部分以获取更多详细信息。

例如,如果产品是书籍,则按作者分区可能是有意义的。在这种情况下,当保存时,可以使用TableRepository<Book>

public record Book([RowKey] string ISBN, string Title, string Author, BookFormat Format, int Pages);

var repo = TableRepository.Create<Product>(storageAccount, "Books",
  partitionKey: x => x.Author);

await repo.PutAsync(book);

请注意您如何根据需要混合和匹配属性和显式lambda表达式。后者优先于前者。

稍后当按特定作者列示/筛选书籍时,可以使用TablePartition<Product>,这样所有查询都自动限制在该作者范围内。

var partition = TablePartition.Create<Book>(storageAccount, "Books", 
  partitionKey: "Rick Riordan");

// Get Rick Riordan books, only from Disney/Hyperion, with over 1000 pages
var query = from book in repo.CreateQuery()
            where 
                book.ISBN.CompareTo("97814231") >= 0 &&
                book.ISBN.CompareTo("97814232") < 0 && 
                book.Pages >= 1000
            select new { book.ISBN, book.Title };

使用表分区处理引用数据也非常方便,例如。物联网分区中所有条目的枚举并不一定是处理你的“真实”数据时所典型要做的,但对于引用数据,它可能会有所帮助。

请注意:如果需要访问由Azure Table Storage管理的实体的Timestamp,只需声明一个具有该名称的属性,其类型为DateTimeOffsetDateTimestring即可读取它。

使用TableRepositoryTablePartition存储的实体使用单独的列来存储属性,这使得浏览数据(以及查询,如上所示!)变得容易。

请注意:分区键和行键也可以指定为Guid类型。

如果不需要单独的列,通过DocumentRepositoryDocumentPartition也提供基于文档的存储。

文档存储

DocumentRepository.CreateDocumentPartition.Create工厂方法提供对基于文档的存储的访问,公开与列存储相似的API。

文档仓库会将实体作为单个文档列持久化,同时保留类型和版本信息,以便在应用级别按需处理版本。

API与列存储仓库大致相同(文档仓库实现了相同的底层ITableStorage接口)

public record Product(string Category, string Id) 
{
  public string? Title { get; init; }
  public double Price { get; init; }
  public DateOnly CreatedAt { get; init; }
}

var book = new Product("book", "9781473217386")
{
    Title = "Neuromancer",
    Price = 7.32
};

// Column-based storage
var repo = TableRepository.Create<Product>(
    CloudStorageAccount.DevelopmentStorageAccount,
    tableName: "Products",
    partitionKey: p => p.Category,
    rowKey: p => p.Id);

await repo.PutAsync(book);

// Document-based storage
var docs = DocumentRepository.Create<Product>(
    CloudStorageAccount.DevelopmentStorageAccount,
    tableName: "Documents",
    partitionKey: p => p.Category,
    rowKey: p => p.Id
    serializer: [SERIALIZER]);

await docs.PutAsync(book);

如果没有提供,序列化器默认为基于System.Text.JsonDocumentSerializer.Default

以下截图展示了Azure Storage Explorer的存储差异。

Screenshot of entity persisted with separate columns for properties

Screenshot of entity persisted as a document

保存在文档表中的Type列是持久化实体的Type.FullName,而版本是其实例集合的[主].[次]版本。这可以用于高级数据迁移场景。主版本和次版本组件还作为单独的列提供,以便使用IDocumentRepository.EnumerateAsync(predicate)更容易地按各种版本范围查询。

除了默认的内置基于JSON的纯文本序列化器(它使用System.Text.Json包)之外,还有针对基于文档的存储的其他替代序列化器,包括各种二进制序列化器,它们将还将文档持久化为字节数组。

Json.NET Bson MessagePack Protobuf

您可以通过以下方式将序列化器传递给工厂方法

var repo = TableRepository.Create<Product>(...,
    serializer: [JsonDocumentSerializer|BsonDocumentSerializer|MessagePackDocumentSerializer|ProtobufDocumentSerializer].Default);

请注意:当使用替代序列化器时,实体可能需要注解底层库所需的任何属性。

属性

如果您想避免使用工厂方法中的字符串,还可以注解实体类型以修改默认值。

  • [Table("tableName")]:类级别的属性,用于在没有提供值时更改默认值
  • [PartitionKey]:注解应该用作分区键的属性
  • [RowKey]:注解应该用作行键的属性。

传递给工厂方法的值会覆盖声明性属性。

对于上面的产品示例,您的记录实体可以是

[Table("Products")]
public record Product([PartitionKey] string Category, [RowKey] string Id) 
{
  public string? Title { get; init; }
  public double Price { get; init; }
}

创建存储库不需要除了存储账户之外的任何参数

var repo = TableRepository.Create<Product>(CloudStorageAccount.DevelopmentStorageAccount);

此外,如果您想从持久性中省略特定属性,您可以使用[Browsable(false)]对其进行注解,当持久化和读取实体时,它将被跳过。

TableEntity 支持

因为这些存储库 API 与直接操作 TableClient 相比,直观得多
,您可能希望通过它们的内置 TableEntity 属性来检索/枚举实体,如 PartitionKeyRowKeyTimestampETag。对于这种情况,我们也支持使用无 (泛型) 实体类型参数的工厂方法 TableRepository.Create(...)TablePartition.Create(...) 创建 ITableRepository<TableEntity>ITablePartition<TableEntity>

例如,假设您知道在上述示例中保存的所有 Region 实体,您可以使用工具的 Code 作为 RowKey,您可以直接枚举所有区域,而无需使用 Region 类型

var account = CloudStorageAccount.DevelopmentStorageAccount; // or production one
var repo = TablePartition.Create(storageAccount, 
  tableName: "Reference",
  partitionKey: "Region");

// Enumerate all regions within the partition as plain TableEntities
await foreach (TableEntity region in repo.EnumerateAsync())
   Console.WriteLine(region.RowKey);

您可以通过仅使用实体索引器来访问和添加其他属性,以后可以通过调用 PutAsync 来持久化

await repo.PutAsync(
    new TableEntity("Book", "9781473217386") 
    {
        ["Title"] = "Neuromancer",
        ["Price"] = 7.32
    });

var entity = await repo.GetAsync("Book", "9781473217386");

Assert.Equal("Neuromancer", entity["Title"]);
Assert.Equal(7.32, (double)entity["Price"]);

赞助商

Clarius Org Kirill Osenkov MFB Technologies, Inc. Stephen Shaw Torutek DRIVE.NET, Inc. Ashley Medway Keith Pickford Thomas Bolon Kori Francis Toni Wenzel Giorgi Dalakishvili Uno Platform Dan Siegel Reuben Swartz Jacob Foshee alternate text is missing from this package README image Eric Johnson Ix Technologies B.V. David JENNI Jonathan Oleg Kyrylchuk Charley Wu Jakob Tikjøb Andersen Seann Alexander Tino Hager Mark Seemann Ken Bonny Simon Cropp agileworks-eu sorahex Zheyu Shen Vezel ChilliCream 4OTC

成为一个赞助商  

了解更多关于 GitHub Sponsors 的信息

产品 兼容的以及额外的计算目标框架版本。
.NET net5.0 已计算。 net5.0-windows 已计算。 net6.0 兼容。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 已计算。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 已计算。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。
.NET Core netcoreapp2.0 已计算。 netcoreapp2.1 已计算。 netcoreapp2.2 已计算。 netcoreapp3.0 已计算。 netcoreapp3.1 已计算。
.NET Standard netstandard2.0 兼容。 netstandard2.1 兼容。
.NET Framework net461 已计算。 net462 已计算。 net463 已计算。 net47 已计算。 net471 已计算。 net472 已计算。 net48 已计算。 net481 已计算。
MonoAndroid monoandroid 已计算。
MonoMac monomac 已计算。
MonoTouch monotouch 已计算。
Tizen tizen40 已计算。 tizen60 已计算。
Xamarin.iOS xamarinios 已计算。
Xamarin.Mac xamarinmac 已计算。
Xamarin.TVOS xamarintvos 已计算。
Xamarin.WatchOS xamarinwatchos 已计算。
兼容的目标框架
包含的目标框架(在包中)
有关 目标框架.NET 标准的更多信息,请参阅。

NuGet 库包 (4)

显示依赖 Devlooped.TableStorage 的前 4 个 NuGet 库包

下载
Devlooped.TableStorage.Protobuf

用于文档存储库的二进制序列化程序 Protocol Buffers。

Devlooped.TableStorage.MessagePack

用于文档存储库的二进制序列化程序 MessagePack。

Devlooped.TableStorage.Bson

用于文档存储库的二进制序列化程序 BSON。

Devlooped.TableStorage.Newtonsoft

用于基于文档的存储库的Json.NET序列化器。

GitHub仓库

该软件包没有被任何流行的GitHub仓库使用。

版本 下载 最后更新
5.2.0 95 7/24/2024
5.2.0-rc.1 72 7/13/2024
5.2.0-rc 152 7/10/2024
5.2.0-beta 168 7/6/2024
5.1.2 1,302 1/25/2024
5.1.1 277 10/4/2023
5.1.0 642 8/11/2023
4.1.3 1,174 1/20/2023
4.1.2 784 1/16/2023
4.0.0 1,484 8/26/2022
4.0.0-rc.1 100 8/26/2022
4.0.0-rc 305 8/15/2022
4.0.0-beta 457 5/17/2022
4.0.0-alpha 326 5/4/2022
3.2.0 1,623 12/13/2021
3.1.1 1,328 8/29/2021
3.1.0 1,225 8/13/2021
3.0.3 1,202 7/28/2021
3.0.2 1,284 7/1/2021
2.0.2 1,318 6/23/2021
2.0.1 1,305 6/17/2021
2.0.0 1,284 6/16/2021
1.3.0 1,060 5/31/2021
1.2.1 447 5/29/2021
1.2.0 459 5/26/2021
1.0.4 572 5/16/2021