我一直在阅读有关 key 的数据存储区文档。
在文档中说
这是结果
以下是我的样本。 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#从数据存储区实体中检索 key 以更新和删除记录?
最佳答案
通过调用文档中提到的Entity.Key
属性
Key key = entity.Key;
_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/ key ,则现在应该能够根据该ID/ key 进行更新
编辑项目时,您可以
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();
}
//...
}
然后在需要时将其作为依赖项注入(inject)。
例如,
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
中,抽象存储被注入(inject)并用于获取要在 View 中显示的项目然后,您应该能够在 View /页面中访问列表中的项目。
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 />
关于c# - 从数据存储中检索 key (更新和删除实体),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50330404/