在 MVC 6 下,使用 ADO.NET 的 DataTable 的替代方案是什么?

What's the alternative to DataTable with ADO.NET under MVC 6?

我正在创建一个 MVC 6 项目,我宁愿使用 Classic ADO.net 而不是 Entity Framework 7。但是它说找不到两个 DataTableSqlDataAdapter。我有一个 using System.DataSystem.Data.SqlClient 语句。在我尝试构建项目之前,它不会显示错误。

我想我在某处读到这两个名称 space 没有在新版本中实现。如果是这样,是否有其他替代方法,或者我是否缺少依赖项或 using 语句?

代码:

public static DataTable GetLog(string appName)
{
    DataTable table = new DataTable("ApplicationLog");
    SqlDataAdapter da = null;

    using (SqlConnection conn = DB.GetSqlConnection())
    {
        SqlCommand cmd = new SqlCommand("select * from ApplicationLog where application_name = @appname", conn);
        cmd.Parameters.Add(new SqlParameter("appname", System.Data.SqlDbType.NVarChar, 100));
        cmd.Parameters["appname"].Value = appName;


        da = new SqlDataAdapter(cmd);

        int res = da.Fill(table);
    }

    return table;
}

我的project.json

{
    "userSecretsId": "aspnet5-ASPDemo-b25bb1cc-00e6-401e-9f49-5b59c08a030f",
    "version": "1.0.0-*",
    "compilationOptions": {
        "emitEntryPoint": true
    },

    "dependencies": {
        "Bestro": "1.0.0-*",
        "EntityFramework.Core": "7.0.0-rc1-final",
        "EntityFramework.Commands": "7.0.0-rc1-final",
        "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
        "Microsoft.ApplicationInsights.AspNet": "1.0.0-rc1",
        "Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-final",
        "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc1-final",
        "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final",
        "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
        "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
        "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
        "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
        "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
        "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
        "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",
        "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",
        "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final",
        "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-final",
        "Microsoft.Extensions.Logging": "1.0.0-rc1-final",
        "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
        "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
        "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc1-final",
        "DataTables.AspNet.AspNet5": "2.0.0-beta2"
    },

    "commands": {
        "web": "Microsoft.AspNet.Server.Kestrel",
        "ef": "EntityFramework.Commands"
    },

    "frameworks": {
        "dnx451": {
            "frameworkAssemblies": {
                "System.configuration": "4.0.0.0",
                "System.Data": "4.0.0.0"
            }
        } 
    },

    "exclude": [
        "wwwroot",
        "node_modules"
    ],
    "publishExclude": [
        "**.user",
        "**.vspscc"
    ],
    "scripts": {
        "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
    }
}

我最终尝试了很多不同的组件以试图让它合规。如果有使用参考,请告诉我。

你应该 post 你的 project.json

引用 System.Data 并删除 project.json 中的 dnxcore50 让我编译上面的代码:

"frameworks": {
    "dnx451": {
        "frameworkAssemblies": {
            "System.Data": "4.0.0.0"
        }
    }
}

我理解这个问题,因为我喜欢在我的 C# 代码中使用现有的存储过程和动态 SQL 查询。为每个使用具有可为空属性的现有实体保存新查询结果的查询创建新实体不是一个好主意。此外,我喜欢使用 Web API 以 JSON 格式提供数据,以供前端使用 JavaScript.

编写

另一方面 Entity Framework 包含执行行 SQL 查询并将结果保存在没有使用实体的对象中的方法。我在 中发布了代码片段,其中一个可以使用。我很快就想起了这个想法。

需要将连接字符串包含到应用程序的配置文件中。例如,您可以创建 appsettings.json

{
  "Data": {
    "MyDbConnectionString": "Server=(localdb)\mssqllocaldb;Database=ApplicationDb;Trusted_Connection=True;MultipleActiveResultSets=true",
  }
}

然后你创建虚拟上下文class

public class MyDbContext : DbContext
{
}

没有任何实体。您将仅使用 DbContext 来保持数据库连接。

然后你写Startup.cs根据"appsettings.json".

的内容构造Configuration属性
public class Startup
{
    // property for holding configuration
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
            .AddEnvironmentVariables();
        // save the configuration in Configuration property
        Configuration = builder.Build();
    }
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc()
            .AddJsonOptions(options => {
                options.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            });
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<MyDbContext>(options => {
                options.UseSqlServer(Configuration["Data:MyDbConnectionString"]);
            });
    }
    ...
}

现在你已经 MyDbContext 注入了,可以在上下文中使用它,你可以使用

using (var cmd = MyDbContext.Database.GetDbConnection().CreateCommand()) {
    cmd.CommandText = "select * from ApplicationLog where application_name = @appname";
    if (cmd.Connection.State != ConnectionState.Open)
        cmd.Connection.Open();

    cmd.Parameters.Add(new SqlParameter("@appname", SqlDbType.NVarChar, 100) {
        Value = appName
    });

    da = new SqlDataAdapter(cmd);

    int res = da.Fill(table);
}

我个人更喜欢使用List<dynamic>ExecuteReader/ExecuteReaderAsync而不是DataTable(参见中的代码),但事实并非如此重要。

Oleg 的 post 很有帮助。看起来在最新版本中,如果您使用的是内置 DI,DbContext 将需要一个采用 DbContextOptions 的构造函数。有几种不同的风格,但您不能再只有 "dummy" 空 DbContext class。

https://docs.efproject.net/en/latest/miscellaneous/configuring-dbcontext.html