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

时间:2018-12-17 12:36:38

标签: c# sql wcf

我是C#的新手,对如何建立与 MySql数据库的连接不是很熟悉。

我确实有一个名为 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;        }
    }
}

我正在尝试做出选择语句,并将结果分配给本地列表

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;

但是,当我尝试将其作为WCF服务运行时,出现以下错误:

  

添加服务失败。服务元数据可能无法访问。使   确保您的服务正在运行并公开元数据。

该服务在添加上述代码之前 正常工作,因此我认为问题出在我的数据检索方法中。

2 个答案:

答案 0 :(得分:1)

首先,错误详细信息主要表明我们应该公开服务元数据以便在客户端使用服务,但这不能解决我们的问题。
其次,我们应该将OperationContractAttribute添加到操作方法中,并将DataContractAttribute添加到自定义复杂类型中。
我做了一个演示,希望对您有用。
接口和服务实现

[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

<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>

结果。 enter image description here 此外,必须注意的是,如果要在IIS中查询localdb数据库(vs2017内置数据库),则应在承载wcf服务的IIS应用程序池中配置以下内容。

loadUserProfile="true" setProfileEnvironment="true" 

请随时告诉我是否有什么可以帮忙的。

答案 1 :(得分:0)

首先,我建议您将Entity Framework用作ORM

这些是您必须对代码进行的更改。基本上,您尝试在打开连接之前执行读取器:

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;
    }

对代码的一些了解:

  • 尽可能使用var代替显式类型。
  • 使用using()语句来处理SqlCommand或SqlDataReader之类的对象
  • 将连接放在方法内部,或者如果此方法是DAL类的一部分,请创建其他方法以打开/关闭连接。
  • 所有可能在try / cath块内引发异常的语句(例如open或executeReader,这样您就可以知道代码中的错误)。
  • 有重复的语句,例如打开连接,executeReader。