简体   繁体   English

将SQL SELECT查询结果添加到列表

[英]Add SQL SELECT query result to List

I am new to C# and not very familiar with how a connection to a MySql database should be established. 我是C#的新手,对如何建立与MySql数据库的连接不是很熟悉。

I do have a table called packages which contains, for which i created a model: 我确实有一个名为packages的表,其中包含我为其创建的模型:

namespace CService.Models
{
    public class Package
    {   

        public int id { get; set; }
        public String name { get; set; }
        public String description { get; set; }
        public Boolean tracking { get; set; }
        public int senderCityId { get; set; }
        public int destinationCityId { get; set; }
        public int senderId { get; set; }
        public int receiverId { get; set; }

        public Package(int id, string name, string description, Boolean tracking, int senderCityId,
            int destinationCityId, int senderId, int receiverId)
        {
            this.id = id;
            this.name = name;
            this.description = description;
            this.tracking = tracking;
            this.senderCityId = senderCityId;
            this.destinationCityId = destinationCityId;
            this.senderId = senderId;
            this.receiverId = receiverId;        }
    }
}

I am trying to make a select statement and assign the result to a local list : 我试图做出一条选择语句,并将结果分配给本地列表

MySqlConnection conn = new MySqlConnection("server = localhost; user id = root; database=assignment_four; password=Mysqlpassword123");

        public List<Package> getPackages()
        {

            List<Package> packages = new List<Package>();
            conn.Open();
            MySqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = "SELECT * from packages";

            MySqlDataReader reader = cmd.ExecuteReader();

            try
            {
                conn.Open();
                reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    packages.Add(new Package(
                        reader.GetInt32(reader.GetOrdinal("id")),
                        reader.GetString(reader.GetOrdinal("name")),
                        reader.GetString(reader.GetOrdinal("description")),
                        reader.GetBoolean(reader.GetOrdinal("tracking")),
                        reader.GetInt32(reader.GetOrdinal("senderCity_id")),
                        reader.GetInt32(reader.GetOrdinal("destinationCity_id")),
                        reader.GetInt32(reader.GetOrdinal("sender_id")),
                        reader.GetInt32(reader.GetOrdinal("receiver_id"))

                    ));

                }
                reader.Close();
            }
            catch (Exception exp)
            {
                throw;
            }
            finally
            {

                conn.Close();
            }

        return packages;

However, when i try to run this, as a WCF service, i get the following error: 但是,当我尝试将其作为WCF服务运行时,出现以下错误:

Failed to add a service. 添加服务失败。 Service metadata may not be accessible. 服务元数据可能无法访问。 Make sure your service is running and exposing metadata. 确保您的服务正在运行并公开元数据。

The service was working before adding the above code, so I assume the problem resides in my data retrieval approach. 添加上述代码之前,该服务已经正常工作,因此我认为问题出在我的数据检索方法中。

First, the error details mainly indicate that we should expose service metadata in order to consume the service on the client side, but it could not solve our problem. 首先,错误详细信息主要表明我们应该公开服务元数据以便在客户端使用服务,但这无法解决我们的问题。
Secondly, we should add OperationContractAttribute to the operation method and add DataContractAttribute to the custom complex type. 其次,我们应该将OperationContractAttribute添加到操作方法,并将DataContractAttribute添加到自定义复杂类型。
I have made a demo, wish it is useful to you. 我做了一个演示,希望对您有用。
Interface and Service implement 接口和服务实施

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [WebGet(RequestFormat =WebMessageFormat.Json,ResponseFormat =WebMessageFormat.Json)]
    List<Product> GetProducts(); }
[DataContract]
public class Product
{
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public int Price { get; set; }
    public Product(int id, string name, int price)
    {
        this.ID = id;
        this.Name = name;
        this.Price = price;
    } }
public class Service1 : IService1
{

    public List<Product> GetProducts()
    {
        List<Product> products = new List<Product>();
        SqlConnection connection = new SqlConnection(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DataStore;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
        SqlCommand command = new SqlCommand("select * from Products", connection);
        connection.Open();
        SqlDataReader reader = command.ExecuteReader();
        while (reader.Read())
        {
            products.Add(new Product(reader.GetInt32((reader.GetOrdinal("Id"))), reader.GetString(reader.GetOrdinal("Name")), reader.GetInt32(reader.GetOrdinal("Price"))));
        }
        reader.Close();
        connection.Close();

        return products;
    }
}

web.config web.config中

<system.serviceModel>
<services>
  <service name="WcfService1.Service1">
    <endpoint address="" binding="webHttpBinding" contract="WcfService1.IService1" behaviorConfiguration="rest"></endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="rest">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" httpGetUrl="mex"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

Result. 结果。 在此处输入图片说明 Besides, one thing must be noted is that if we want to query the localdb database(vs2017 built-in database) in IIS, we should configure the following in the IIS Application Pool which hosted the wcf service. 此外,必须注意的是,如果要在IIS中查询localdb数据库(vs2017内置数据库),则应在承载wcf服务的IIS应用程序池中配置以下内容。

loadUserProfile="true" setProfileEnvironment="true" 

Feel free to let me know if there is anything I can help with. 请随时告诉我是否有什么我可以帮助的。

First of all, I recommend you to use Entity Framework as ORM . 首先,我建议您将Entity Framework用作ORM

These are the changes you have to make to your code. 这些是您必须对代码进行的更改。 Basically you are trying to execute the reader before opening the connection: 基本上,您尝试在打开连接之前执行读取器:

public List<Package> getPackages()
    {
        var conn = new MySqlConnection("server = localhost; user id = root; database=assignment_four; password=Mysqlpassword123");
        var packages = new List<Package>();

        try
        {
            conn.Open();
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = "SELECT * from packages";

                using (var reader = cmd.ExecuteReader())
                {

                    while (reader.Read())
                    {
                        packages.Add(new Package(
                            reader.GetInt32(reader.GetOrdinal("id")),
                            reader.GetString(reader.GetOrdinal("name")),
                            reader.GetString(reader.GetOrdinal("description")),
                            reader.GetBoolean(reader.GetOrdinal("tracking")),
                            reader.GetInt32(reader.GetOrdinal("senderCity_id")),
                            reader.GetInt32(reader.GetOrdinal("destinationCity_id")),
                            reader.GetInt32(reader.GetOrdinal("sender_id")),
                            reader.GetInt32(reader.GetOrdinal("receiver_id"))
                        ));

                    }
                    reader.Close();
                }
            }
        }
        catch (Exception exp)
        {
            throw;
        }
        finally
        {
            conn.Close();
        }

        return packages;
    }

Some insight of the code: 代码的一些见解:

  • Use var whenever you can instead the explicit type. 尽可能使用var代替显式类型。
  • Use using() statement for disposing objects like SqlCommand or SqlDataReader 使用using()语句来处理SqlCommand或SqlDataReader之类的对象
  • Put the connection inside the method, or if this method is part of a DAL class, create other method to open/close connection if needed. 将连接放在方法内部,或者如果此方法是DAL类的一部分,请根据需要创建其他方法来打开/关闭连接。
  • All the statements that can throw exceptions inside a try/cath block (like open or executeReader, that way you will know whats wrong on your code). 所有可能在try / cath块内引发异常的语句(例如open或executeReader,这样您就可以知道代码中的错误)。
  • There were duplicated statements, like open connection, executeReader. 有重复的语句,例如打开连接,executeReader。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM