Devlooped.TableStorage 5.2.0
前缀已保留
dotnet add package Devlooped.TableStorage --version 5.2.0
NuGet\Install-Package Devlooped.TableStorage -Version 5.2.0
<PackageReference Include="Devlooped.TableStorage" Version="5.2.0" />
paket add Devlooped.TableStorage --version 5.2.0
#r "nuget: Devlooped.TableStorage, 5.2.0"
// 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 的仓储模式
注意:此库是最新 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
,只需声明一个具有该名称的属性,其类型为DateTimeOffset
、DateTime
或string
即可读取它。
使用TableRepository
和TablePartition
存储的实体使用单独的列来存储属性,这使得浏览数据(以及查询,如上所示!)变得容易。
请注意:分区键和行键也可以指定为
Guid
类型。
如果不需要单独的列,通过DocumentRepository
和DocumentPartition
也提供基于文档的存储。
文档存储
DocumentRepository.Create
和DocumentPartition.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.Json
的DocumentSerializer.Default
。
以下截图展示了Azure Storage Explorer的存储差异。
保存在文档表中的Type
列是持久化实体的Type.FullName
,而版本是其实例集合的[主].[次]
版本。这可以用于高级数据迁移场景。主版本和次版本组件还作为单独的列提供,以便使用IDocumentRepository.EnumerateAsync(predicate)
更容易地按各种版本范围查询。
除了默认的内置基于JSON的纯文本序列化器(它使用System.Text.Json包)之外,还有针对基于文档的存储的其他替代序列化器,包括各种二进制序列化器,它们将还将文档持久化为字节数组。
您可以通过以下方式将序列化器传递给工厂方法
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
属性来检索/枚举实体,如 PartitionKey
、RowKey
、Timestamp
和 ETag
。对于这种情况,我们也支持使用无 (泛型) 实体类型参数的工厂方法 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"]);
赞助商
产品 | 版本 兼容的以及额外的计算目标框架版本。 |
---|---|
.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 已计算。 |
-
.NETStandard 2.0
- Azure.Data.Tables (≥ 12.8.1)
- Devlooped.CloudStorageAccount (≥ 1.2.0)
- Microsoft.OData.Client (≥ 7.21.3)
- System.Text.Json (≥ 6.0.6)
-
.NETStandard 2.1
- Azure.Data.Tables (≥ 12.8.1)
- Devlooped.CloudStorageAccount (≥ 1.2.0)
- Microsoft.OData.Client (≥ 7.21.3)
- System.Text.Json (≥ 6.0.6)
-
net6.0
- Azure.Data.Tables (≥ 12.8.1)
- Devlooped.CloudStorageAccount (≥ 1.2.0)
- Microsoft.OData.Client (≥ 7.21.3)
- System.Text.Json (≥ 6.0.6)
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 |