首页 > 解决方案 > 将对象转换为特定类型c#

问题描述

我正在用 c# 编写一个 Web 应用程序,在其中我查阅了 Azure 中的 CosmoDB 中的数据。这个 cosmoDB 的文档是一些数据结构的 Json,我在我的 Web 应用程序中定义为模型。问题是,当查询在数据库中具有不同类型的结构时,我必须将其作为对象类型进行,以便稍后将其转换为特定类型并以 html 代码在屏幕上显示。实际上,我拥有的代码是根据我的应用程序为您提供修改的 Azure 教程的代码。

代码如下:

namespace todo
{
 using System.Web.Mvc;
 using System.Web.Optimization;
 using System.Web.Routing;
 using System.Collections;
 using System;
 using System.Collections.Generic;
 using System.Configuration;
 using System.Linq;

 public class MvcApplication : System.Web.HttpApplication
 {
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        DocumentDBRepository<Object>.Initialize();
    }
  }
}

然后 Home 控制器使:

    [ActionName("ECCE")]
    public async Task<ActionResult> ECCEAsync(string id)
    {
        var items = await DocumentDBRepository<Object>.GetItemsAsync(id);
        return View((ECCE_SupportData)items);
    }

DocumentDBRepository 类在哪里:

        public static async Task<IEnumerable<T>> GetItemsAsync(string collectionId)
    {
        List<T> results = new List<T>();

        try
        {
            IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
                UriFactory.CreateDocumentCollectionUri(DatabaseId, collectionId),
                new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true })
                .AsDocumentQuery();

            while (query.HasMoreResults)
            {
                results.AddRange(await query.ExecuteNextAsync<T>());
            }
        }
        catch (Exception)
        {
            return results;
        }

        return results;
    }

稍后将对象列表传递给 html 以在屏幕上查看它们:

<script type="text/javascript" language="javascript" src="../../Scripts/TableFilter/tablefilter.js"></script>

@model IEnumerable<todo.Models.ECCE.ECCE_SupportData>
@{
    ViewBag.Title = "Data";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>ECCE Data</h2>

@if (Model.Count() != 0)
{
    <table class="table" id="ECCETable">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.ECCE_CnfStatus)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ECCE_ComsStatus.ComStatus)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ECCE_ComsStatus.UltimoError)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ECCE_Status.AppVersion.IdApp)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ECCE_Status.AppVersion.ReqVersion)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ECCE_Status.AppVersion.SwVersion)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ECCE_Status.AppStatus)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ECCE_UvStatus.NumUVs)
            </th>
            
    </table>

问题是,在 HomeController 中,当我尝试将对象转换为我的数据结构 ECCE_SuportData 时出现错误:您无法将类型为“System.Collections.Generic.List`1 [System.Object]”的对象转换为类型'todo.Models。ECCE.ECCE_SupportData '

有谁知道我如何将对象转换为这个数据结构?提前致谢。

标签: c#azurewebazure-cosmosdb

解决方案


问题的根源在于您实现存储库的方式根本上是错误的。我知道您使用的是 Azure 示例,但这些示例不一定是实现它的最佳方式。静态存储库实现永远不会在您需要使用多种类型的文档的现实生活场景中工作。

您需要做的是为每个需要操作的对象类型创建此存储库的实例。这意味着,删除static关键字并将存储库实例注册为应用程序生命周期的单例。

你可以在这里找到一个(有点过时但)体面的实现你需要做的事情

此外,对于最新的 CosmosDB 相关示例,我强烈建议您使用官方 CosmosDB .NET Github 存储库。他们有一个文件夹,里面装满了几乎任何东西的样本。

但是,如果您想使用更像 ORM 的实现,您还应该看看Cosmonaut

这样,您的所有代码都将变为:

var items = await cosmoStore.Query().ToListAsync;

选择完全取决于您,什么最适合您的要求。

免责声明:我是 Cosmonaut 的创造者


推荐阅读