【问题标题】:Asp Core 1.1, DataTable exists in bothAsp Core 1.1,DataTable 两者都存在
【发布时间】:2017-08-18 02:14:56
【问题描述】:

我正在开发一个 dot net core 1.1 应用程序,我试图在其中使用Accord.Net。根据本页 (Naive Bayes) 中的示例,我需要将从 DB 检索到的数据转换为 DataTable。

问题是在使用 DataTable 时出现此错误:

“Shim, ...”和“Shim, ...”中都存在“DataTable”类型 'System.Data.Common, ...'

即使我使用这个:

DataTable learningDataNotCodifiedAsDataTable = new DataTable();

或者这个:

System.Data.DataTable learningDataNotCodifiedAsDataTable = new System.Data.DataTable();

TG。

【问题讨论】:

  • 您实际上不需要将从数据库检索到的数据转换为数据表。您真正需要的是将数据转换为 double[][] 或 int[][] 数组,然后您可以将其传递给 NaiveeBayesLearning 的 .Learn 方法。请检查您链接页面中的第二个示例,以防有帮助!

标签: datatable asp.net-core reference asp.net-core-mvc accord.net


【解决方案1】:

虽然 DataTable 在 .NET Core 1.1 中不可用,但它现在在 .NET Core 2.0 中可用。如果您可以将项目升级到 .NET Core 2.0,那么您将能够在代码中使用它。

但是,如果您现在无法切换到 .NET Core 2.0,那么请注意,您不需要将 DataTables 与 Accord.NET 框架中的任何方法一起使用。给出或显示它们只是因为它们可以提供一些额外的便利,但它们并不是真正必需的,如下例所示:

string[] columnNames = { "Outlook", "Temperature", "Humidity", "Wind", "PlayTennis" };

string[][] data =
{
    new string[] { "Sunny", "Hot", "High", "Weak", "No" },
    new string[] { "Sunny", "Hot", "High", "Strong", "No" },
    new string[] { "Overcast", "Hot", "High", "Weak", "Yes" },
    new string[] { "Rain", "Mild", "High", "Weak", "Yes" },
    new string[] { "Rain", "Cool", "Normal", "Weak", "Yes" },
    new string[] { "Rain", "Cool", "Normal", "Strong", "No" },
    new string[] { "Overcast", "Cool", "Normal", "Strong", "Yes" },
    new string[] { "Sunny", "Mild", "High", "Weak", "No" },
    new string[] { "Sunny", "Cool", "Normal", "Weak", "Yes" },
    new string[] {  "Rain", "Mild", "Normal", "Weak", "Yes" },
    new string[] {  "Sunny", "Mild", "Normal", "Strong", "Yes" },
    new string[] {  "Overcast", "Mild", "High", "Strong", "Yes" },
    new string[] {  "Overcast", "Hot", "Normal", "Weak", "Yes" },
    new string[] {  "Rain", "Mild", "High", "Strong", "No" },
};

// Create a new codification codebook to
// convert strings into discrete symbols
Codification codebook = new Codification(columnNames, data);

// Extract input and output pairs to train
int[][] symbols = codebook.Transform(data);
int[][] inputs = symbols.Get(null, 0, -1); // Gets all rows, from 0 to the last (but not the last)
int[] outputs = symbols.GetColumn(-1);     // Gets only the last column

// Create a new Naive Bayes learning
var learner = new NaiveBayesLearning();

NaiveBayes nb = learner.Learn(inputs, outputs);

// Consider we would like to know whether one should play tennis at a
// sunny, cool, humid and windy day. Let us first encode this instance
int[] instance = codebook.Translate("Sunny", "Cool", "High", "Strong");

// Let us obtain the numeric output that represents the answer
int c = nb.Decide(instance); // answer will be 0

// Now let us convert the numeric output to an actual "Yes" or "No" answer
string result = codebook.Translate("PlayTennis", c); // answer will be "No"

// We can also extract the probabilities for each possible answer
double[] probs = nb.Probabilities(instance); // { 0.795, 0.205 }

【讨论】:

  • 你说得对DataTable 没必要,但在我完全构建项目后,问题扩大了。现在DirectoryFileProcessshimSystem.IO.FileSystemSystem.Diagnostics.Process 之间是通用的。这三个和任何类似的任何进一步的解决方案?
  • 由于您在使用 Shim 时遇到错误,我猜您使用的是 NuGet 的“Portable Accord.NET”版本。如果您已更新到 Net Core 2.0,则可以改用来自 NuGet 的官方 Accord.NET 库。
  • 好的,我刚刚看到您现在无法升级。请尝试在 NuGet 上安装最新的 Accord.NET 预发布包 - 我几乎可以肯定该版本应该适用于 NET Core 1.1。
  • @ConductedClever 您可以使用 extern alias 选择用于DirectoryFileProcess 的库。请参阅我的答案中的更新以供参考,只需将 System.Data.Common 替换为您在 csprojcs 文件中都需要的命名空间。
  • @Cesar 我正在检查portable.accord 的预发布版本!你是完全正确的。感谢您对 Accord 的大力支持。
【解决方案2】:

如果您在程序集中有System.Data 程序集并且不想或无法删除它,那么您可以使用extern alias 绕过它,但是当我使用它绕过此错误时,我得到'DataTable' does not contain a constructor that takes 0/1 arguments 错误,如果相信this discussion,原因是:

System.Data.DataTable 作为空类存在于 .Net core(1.0,1.1) 中 完成接口实现。这个问题是为了追踪 需要引入 API 以在 .Net 中提供类似 API 的 DataTable 核心。

它仅在 .NET Core 2.0 中发生了变化,请参阅 this SO post。我在 .NET Core 2.0 项目(在 VS 2017 15.3 中)中尝试了你的代码,然后它才能正常工作。

更新: 我的意思是这个程序集。

但是正如你所说你只有 NUGET 包,那么你也可以在你的 csproj 文件中为 Nuget 包使用别名,如下所示(我使用了System.Data.Common,如果需要,你可以用你的 Shim 包替换它):

 <Target Name="DataAlias" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
    <ItemGroup>
      <ReferencePath Condition="'%(FileName)' == 'System.Data.Common'">
        <Aliases>MyData</Aliases>
      </ReferencePath>
    </ItemGroup>
  </Target>

然后像这样在 C# 中引用它:

extern alias MyData; //1st line in .cs file
...
using MyData::System.Data;
...
DataTable datatable = new DataTable();

但是你仍然不能使用,因为你会得到我上面写的关于构造函数的错误。在这里你有 2 个选项来解决这个问题:

  1. 切换到 .NET Core 2.0
  2. 如果适合您,请尝试使用解决方法from this post 使用DbDataReader

【讨论】:

  • “如果您在程序集中有 System.Data 程序集”是什么意思?在 NuGet 包和 SDK 包中,我什至没有系统包。还有其他地方可以搜索吗?在那之后,你的意思是在dot net core 1.1中没有解决方案?
  • @ConductedClever 请检查更新的答案。是的,不幸的是没有解决方案,就像这里和 GitHub 上关于 DbSet 和 .NET Core 的几篇文章一样。而且只有 2 个选项:1)等待 .NET Core 2.0; 2) 编写你自己的实现(听起来像个笑话)
  • 我很高兴听到 .net core 2.0 是最终版本,但现在我正努力保持 dot net core 版本以保持低成本。一旦其他解决方案结束,我会将您的答案标记为已接受。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多