Dan*_*ick 9 c# google-app-engine google-cloud-datastore asp.net-core razor-pages
我一直在阅读关于密钥的数据存储文档.
在文档中说
"一个键存储为一个对象而不是一个值."
以下是我的样本.ID是我试图检索以更新和删除实体的密钥
显示结果
@page
@using TestApp.Models
@model AllSportsStoreModel
<h2>Index</h2>
<p>
<a asp-page="SportsStore">New Item</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayName("ID")
</th>
<th>
@Html.DisplayName("Name")
</th>
<th>
@Html.DisplayName("Price")
</th>
<th>Edit | Delete</th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < Model.SportsStoreList.Count; i++) {
<tr>
<td>
@Html.DisplayFor(model => model.SportsStoreList[i].Id)
</td>
<td>
@Html.DisplayFor(model => model.SportsStoreList[i].PName)
</td>
<td>
@Html.DisplayFor(model => model.SportsStoreList[i].Price)
</td>
<td>
<a asp-page="EditStore" asp-route-Id="SportsStoreList[i].Id">Edit</a> |
<a asp-page-handler="Delete" asp-route-Id="SportsStoreList[i].Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
<br />
Run Code Online (Sandbox Code Playgroud)
代码背后:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Google.Cloud.Datastore.V1;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using TestApp.Models;
namespace TestApp.Pages
{
public class AllSportsStoreModel : PageModel
{
private readonly ISportsStore stores;
public AllSportsStoreModel(ISportsStore stores)
{
this.stores = stores;
}
[BindProperty]
public List<Item> SportsStoreList { get; set; }
public IActionResult OnGet()
{
SportsStoreList = stores.ReadAll();
return Page();
}
}
}
Run Code Online (Sandbox Code Playgroud)
DataStoreSportsStore.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Google.Cloud.Datastore.V1;
namespace TestApp.Models
{
public static class DatastoreBookStoreExtensionMethods
{
public static Key ToKey(this long id) => new Key().WithElement("Sports_db", id);
/// <summary>
/// Make a id given a datastore key.
/// </summary>
/// <param name="key">A datastore key</param>
/// <returns>A item id.</returns>
public static long ToId(this Key key) => key.Path.First().Id;
/// <summary>
/// Create a datastore entity with the same values as item.
/// </summary>
/// <param name="item">The item to store in datastore.</param>
/// <returns>A datastore entity.</returns>
public static Entity ToEntity(this Item item) => new Entity()
{
Key = item.Id.ToKey(),
["PName"] = item.PName,
["Price"] = item.Price,
};
/// <summary>
/// Unpack an itemfrom a datastore entity.
/// </summary>
/// <param name="entity">An entity retrieved from datastore.</param>
/// <returns>An Item.</returns>
public static Item ToItem(this Entity entity) => new Item()
{
Id = entity.Key.Path.First().Id,
PName = (string)entity["PName"],
Price = (string)entity["Price"]
};
}
public class DatastoreSportsStore : ISportsStore
{
string kind = "Sports_db";
private readonly DatastoreDb _db;
public DatastoreSportsStore()
{
_db = DatastoreDb.Create("projectid");
}
public void Create(Item item)
{
var entity = item.ToEntity();
entity.Key = _db.CreateKeyFactory(kind).CreateIncompleteKey();
var keys = _db.Insert(new[] { entity });
item.Id = keys.First().Path.First().Id;
}
public Item Read(long id)
{
return _db.Lookup(id.ToKey())?.ToItem();
}
public List<Item> ReadAll()
{
var query = new Query(kind);
var results = _db.RunQuery(query);
return results.Entities.Select(entity => entity.ToItem()).ToList();
}
public void Update(Item item)
{
_db.Update(item.ToEntity());
}
public void Delete(long id)
{
_db.Delete(id.ToKey());
}
}
}
Run Code Online (Sandbox Code Playgroud)
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ISportsStore, DatastoreSportsStore>();
services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)
Item.cs
namespace TestApp.Models
{
public class Item
{
public long Id { get; set; }
public string PName { get; set; }
public string Price { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
如何从数据存储区实体检索密钥以使用C#更新和删除记录?
如何使用 C# 从数据存储实体检索密钥?
通过Entity.Key调用文档中提到的属性
Key key = entity.Key;
Run Code Online (Sandbox Code Playgroud)
与实体合作
应用程序可以使用 Cloud Datastore API 来创建、检索、更新和删除实体。如果应用程序知道实体的完整密钥(或者可以从其父密钥、种类和标识符派生它),则它可以使用该密钥直接对该实体进行操作。
更新实体
要更新现有实体,请修改先前检索的实体的属性并使用密钥存储它:
_item["Name"] = "John";
_item["Price"] = 12.95;
_db.Update(_item);
Run Code Online (Sandbox Code Playgroud)
删除实体
给定实体的密钥,您可以删除该实体:
_db.Delete(_item.Key);
Run Code Online (Sandbox Code Playgroud)
上面的假设是_item是 类型的变量Entity。
这里有一个非常有用的教程
你可以尝试以下方法。
假设您有一个这样的模型(取自您之前的问题之一)
public class Item {
public string Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
请注意Id
GitHub 上有一些辅助方法的链接。这可以适应您的场景。
喜欢
/// <summary>
/// Make a datastore key given a item's id.
/// </summary>
/// <param name="id">An Item's id.</param>
/// <returns>A datastore key.</returns>
public static Key ToKey(this string id) =>
new Key().WithElement("Sports_db", id);
/// <summary>
/// Make a id given a datastore key.
/// </summary>
/// <param name="key">A datastore key</param>
/// <returns>A item id.</returns>
public static string ToId(this Key key) => key.Path.First().Name;
/// <summary>
/// Create a datastore entity with the same values as item.
/// </summary>
/// <param name="item">The item to store in datastore.</param>
/// <returns>A datastore entity.</returns>
public static Entity ToEntity(this Item item) => new Entity() {
Key = item.Id.ToKey(),
["Name"] = item.Name,
["Price"] = item.Price,
};
/// <summary>
/// Unpack an itemfrom a datastore entity.
/// </summary>
/// <param name="entity">An entity retrieved from datastore.</param>
/// <returns>An Item.</returns>
public static Item ToItem(this Entity entity) => new Item() {
Id = entity.Key.ToId(),
Name = (string)entity["Name"],
Price = (decimal)entity["Price"]
};
Run Code Online (Sandbox Code Playgroud)
这将允许您使用扩展方法来执行以下操作
SportsStoreList = stores.Select(entity => entity.ToItem()).ToList();
Run Code Online (Sandbox Code Playgroud)
这又是取自之前的问题。
现在您已经有了一个 Id/Key 可以使用,您现在应该能够根据 Id/Key 进行更新
编辑项目时,您可以
var entity = item.ToEntity()
_db.Update(entity);
Run Code Online (Sandbox Code Playgroud)
对于删除,您只需将 Id 转换回 Key
var key = item.Id.ToKey();
_db.Delete(key);
Run Code Online (Sandbox Code Playgroud)
更进一步,您可以将数据存储封装在一个抽象后面,该抽象提供 CRUD 功能并将所有数据存储相关功能保留在一个中心区域
public class DatastoreSportsStore : ISportsStore {
string kind = "Sports_db";
private readonly DatastoreDb _db;
public DatastoreSportsStore() {
_db = DatastoreDb.Create("projectid");
}
public void Create(Item item) {
var entity = item.ToEntity();
entity.Key = _db.CreateKeyFactory(kind).CreateIncompleteKey();
var keys = _db.Insert(new[] { entity });
item.Id = keys.First().ToId();
}
public Item Read(string id) {
return _db.Lookup(id.ToKey())?.ToItem();
}
public List<Item> ReadAll() {
var query = new Query(kind);
var results = _db.RunQuery(query);
return results.Entities.Select(entity => entity.ToItem()).ToList();
}
public void Update(Item item) {
_db.Update(item.ToEntity());
}
public void Delete(string id) {
_db.Delete(id.ToKey());
}
}
Run Code Online (Sandbox Code Playgroud)
这样就不需要与页面模型中的数据存储进行交互。
您可以在启动期间向服务集合注册抽象
启动.cs:
public class Startup {
public void ConfigureServices(IServiceCollection services) {
//...
services.AddScoped<ISportsStore, DatastoreSportsStore>();
//...
// Includes support for Razor Pages and controllers.
services.AddMvc();
}
//...
}
Run Code Online (Sandbox Code Playgroud)
然后在需要的地方将其作为依赖项注入。
例如,
AllSportsStore.cshtml.cs
public class AllSportsStoreModel : PageModel {
private readonly ISportsStore stores;
public AllSportsStoreModel(ISportsStore stores) {
this.stores = stores;
}
[BindProperty]
public List<Item> SportsStoreList { get; set; }
public IActionResult OnGet() {
SportsStoreList = stores.ReadAll();
return Page();
}
}
Run Code Online (Sandbox Code Playgroud)
在上面,PageMode注入了抽象存储并用于获取要在视图中显示的项目
然后,您应该能够访问视图/页面中列表中的项目。
AllSportsStore.cshtml
@page
@using TestApp.Models
@model AllSportsStoreModel
<h2>Index</h2>
<p>
<a asp-page="SportsStore">New Item</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayName("ID")
</th>
<th>
@Html.DisplayName("Name")
</th>
<th>
@Html.DisplayName("Price")
</th>
<th>Edit | Delete</th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < Model.SportsStoreList.Count; i++) {
<tr>
<td>
@Html.DisplayFor(model => model.SportsStoreList[i].Id)
</td>
<td>
@Html.DisplayFor(model => model.SportsStoreList[i].Name)
</td>
<td>
@Html.DisplayFor(model => model.SportsStoreList[i].Price)
</td>
<td>
<a asp-page="EditStore" asp-route-Id="@(Model.SportsStoreList[i].Id)">Edit</a> |
<a asp-page-handler="Delete" asp-route-Id="@(Model.SportsStoreList[i].Id)">Delete</a>
</td>
</tr>
}
</tbody>
</table>
<br />
Run Code Online (Sandbox Code Playgroud)