我一直在阅读有关密钥的数据存储文档。
在文档中说
"密钥存储为对象而不是值。"
以下是我的样本。 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 />
代码背后:
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();
}
}
}
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());
}
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ISportsStore, DatastoreSportsStore>();
services.AddMvc();
}
Item.cs
namespace TestApp.Models
{
public class Item
{
public long Id { get; set; }
public string PName { get; set; }
public string Price { get; set; }
}
}
如何从数据存储区实体检索密钥以使用C#更新和删除记录?
答案 0 :(得分:4)
如何使用C#从数据存储区实体检索密钥?
通过在文档
中提及调用Entity.Key
属性
Key key = entity.Key;
使用实体
应用程序可以使用Cloud Datastore API来创建,检索,更新和删除实体。如果应用程序知道实体的完整密钥(或者可以从其父密钥,种类和标识符派生它),它可以使用密钥直接在实体上运行。
更新实体
要更新现有实体,请修改先前检索的实体的属性,并使用密钥存储它:
_item["Name"] = "John";
_item["Price"] = 12.95;
_db.Update(_item);
删除实体
给定实体的密钥,您可以删除实体:
_db.Delete(_item.Key);
上述假设是_item
是Entity
类型的变量。
参考Cloud Datastore Documentation: Entities, Properties, and Keys
按照这里非常有用的教程
Using Cloud Datastore with .NET
您可以尝试以下操作。
假设你有一个这样的模型(取自你以前的一个问题)
public class Item {
public string Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
请注意Id
有一些helper methods on 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"]
};
这将允许您使用扩展方法执行以下操作
SportsStoreList = stores.Select(entity => entity.ToItem()).ToList();
这再次来自上一个问题。
现在,您有一个与您合作的ID /密钥,现在应该可以根据ID /密钥进行更新
编辑项目时,您可以
var entity = item.ToEntity()
_db.Update(entity);
对于删除,您只需将ID转换回密钥
即可var key = item.Id.ToKey();
_db.Delete(key);
更进一步,您可以将数据存储区封装在提供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());
}
}
这样就无需在页面模型中与数据存储区进行交互。
您将在启动期间使用服务集合注册抽象
参考Introduction to Razor Pages in ASP.NET Core
Startup.cs:
public class Startup {
public void ConfigureServices(IServiceCollection services) {
//...
services.AddScoped<ISportsStore, DatastoreSportsStore>();
//...
// Includes support for Razor Pages and controllers.
services.AddMvc();
}
//...
}
然后将其作为所需的依赖项注入。
例如,
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();
}
}
在上面的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 />
答案 1 :(得分:2)