【问题标题】:Classes, and how they relate to one another in C#类,以及它们在 C# 中如何相互关联
【发布时间】:2018-01-24 00:30:18
【问题描述】:

我正在使用 C# 在 Visual Studio 2017 中进行编码,并试图以一种相关的方式来了解属性/模型类(我已经观看了很多小时的教程/示例!)。

我知道我可以创建一个 Customer 类,其中包含 Name、Currency 等属性,以及另一个名为 Address 的类,其中包含电话号码、国家/地区等。

我不明白的是,您如何使用 MS SQL 数据库以关系方式创建这些。例如。我创建了一个客户“ACME Inc.”。它的属性之一是 PrimaryAddress,它设置为“地址”类型,所以我可以直接链接到地址的属性,但是如果我需要从从表中读取的数据创建属性,我不明白该怎么做。当然我可以做 customer1.PrimaryAddress.Country = Canada,或者单独创建一个名为 Address1 的地址对象,但是如何使用 Customer 的属性引用现有的 Address 对象?

例子:

    public class Customer
    {
            public string Name { get; set; }
            public bool Enabled { get; set; }
            public CAddress PriAddress { get; set } //This points to an object created using the CAddress class below. each customer has only 1 primary address
    }

    public class CAddress
    {
            public int CustomerID { get; set; } //This specifies which Customer this address belongs to
            public string Name { get; set; }
            public string MainNum { get; set; }
    }

我不确定我所说的是否有道理,所以如果有任何其他信息有帮助,请告诉我。谢谢!

【问题讨论】:

  • 如果客户可以有多个地址,那么“客户”数据和“地址”数据将位于两个不同的数据库表中。 “地址”表将有一个外键将其指向“客户”表,因此任何给定的“地址”记录都属于特定的“客户”记录。
  • 数据库中的类和表之间的关系不是一种“自然”的关系——它们是完全不相关的东西。您需要一个像实体框架这样的 ORM 来在两者之间进行映射。这是一个很大的主题——实体框架非常复杂。但它基本上可以完成从表中读取数据到类中的所有繁重工作,反之亦然。
  • 嗨大卫,谢谢 - 是的,我的数据库确实有这个设置,这些表是有意义的,但是将它放入 C# 是我的问题 - 当地址属于一个时,我将如何使用类和属性存储数据特定客户?
  • 感谢您的回复 Sharper - 是的,我明白了,我已经知道如何使用 ADO.NET 并正在考虑使用 Dapper(因为我阅读并看到了它比 Entity 快得多的证据)。我可以让类/属性单独工作,这只是将一个与另一个相关联的问题(例如,如果我运行一个 Select 语句加载整个表地址表(包括多个客户),然后加载客户,我如何引用是否已提取属于每个客户的地址?
  • @007bond007 - 您不需要引用它们,只需将属性 Customer.PrimaryAddress 设置为 Address 的实例,并带有对应的 CustomerId。你怎么做 - 你自己的选择。例如:读取客户,按客户 ID 读取地址 - 创建客户,创建地址,设置 customer.PrimaryAddress。或者使用 ORM,您只需要通知 ORM 您希望使用地址加载客户,PrimaryAddress 属性将自动填充。所以属性是“参考”

标签: c# visual-studio oop properties model


【解决方案1】:

您所说的是数据库对象和类之间的映射。
当您从数据库加载数据时,您只需创建具有所有相关属性(其他相关表)的预期类型的​​实例。

 SELECT c.Id
    , c.Name
    , a.Id As AddressId
    , a.Street As AddressStreet
 FROM Customer c
     INNER JOIN Address a ON a.CustomerId = c.Id

var query = "SELECT ...";
using (var connection = new SqlConnection())
using (var command = new SqlCommand(query, connection))
{
    var customers = new List<Customer>();
    connection.Open();
    using (var reader = command.ExecuteReader())
    {
        while(reader.Read())
        {
            var customer = new Customer
            {
                Id = reader.GetInt32(0),
                Name = reader.GetString(1),
                PrimaryAddress = new Address
                {
                    Id = reader.GetInt32(2),
                    Street = reader.GetString(3)
                }
            };

            customers.Add(customer);
        }
    }
}

当然你可以使用一些ORM框架,这样你的映射代码会更加优雅,所有的映射工作都由ORM框架来完成。
返回包含地址的所有客户的实体框架示例

using (var dbContext = new CustomerDbContext(connectionString))
{
    return dbContext.Customers.Include(customer => customer.PrimaryAddress).ToList();
}

【讨论】:

  • 非常感谢!这真的很有帮助。我现在唯一需要做的就是弄清楚如何在 Dapper 中应用它,但是你回答了我的问题,所以再次感谢你 :)
【解决方案2】:

如果我理解正确,您要问的是,如果您检索客户列表(可能只是一个客户)和地址列表(可能只是一个地址),如何将每个地址与每个客户匹配,对?

如果是这种情况,我要做的是为这两个类定义一个公共属性,即:CustomerId,然后,一旦你有了实例,只需遍历两个集合以分配正确的地址通过一个共同的 CustomerId 给客户。

LINQ 使这种关系映射更容易实现。

【讨论】:

    猜你喜欢
    • 2018-11-26
    • 2016-02-08
    • 2011-07-22
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    相关资源
    最近更新 更多