0

我正在添加一个相当大的程序。在这个程序中,有一个从我们的数据库映射的类,其中包含每个员工的所有属性。它有姓名、电话号码、雇用日期等许多信息;总共超过40个属性。

现在,出于我个人的需要,我需要访问这些数据,但我只需要使用其中的四五个属性,而不是所有可用的属性。我将以多种方式操作这个“迷你对象”,例如搜索、返回结果以及类似性质的事物。这是一个小的,虚构的例子来补充我的解释。

public class BigEmployee //mapped from database
{
    public string attr1 {get;set;}
    public string attr2 {get;set;}
    public string attr3 {get;set;}
    public string attr4 {get;set;}
    //...etc, until attribute 40
}

public class SmallEmployee //IF THIS EXISTED, this all that I would need
{
    public string attr1 {get;set;} //same as BigEmployee attr1
    public string attr2 {get;set;} //same as BigEmployee attr2
    public string attr3 {get;set;} //same as BigEmployee attr3
}

和一个示例方法:

public List<SmallEmployee> GetAllEmployees
{
    return EmployeeList;
}

所以,我想知道的是,我该如何解决这个问题?我应该制作一个从主类中提取的单独对象吗?我是否应该每次都访问主类并强制它只返回某些属性?

4

3 回答 3

5

从您提供的信息中无法轻易回答您的问题。不过,我将尝试提供一些一般性指导:

看起来您的项目正在使用某种形式的 ORM,无论它是众多第三方 ORM 之一(实体框架、NHibernate、SimpleData 等)还是自产的。如果是这种情况,那么在自己的类中创建同一实体的“精简”版本实际上没有任何问题。ORM 生成的类应该只是 DTO(数据传输对象),因此其中不应该包含任何业务逻辑。使用此类类的优势在于,根据 ORM,它们可以减少数据库流量(因为它们只带回您使用的列)。

但是(这是一个很大的但是)

它们只适合只读使用

大多数 ORM 依赖于将整个对象或对象图保存回数据库。它们通常不提供对数据库进行更改的方法,除非原始对象以完全 ORM 兼容的实体形式存在于内存中。这些“lite”类最常见的用途是将大量对象列表发送回用户,此时他们将以您的程序惯用的任何方式选择一个对象,然后程序将检索完整的实体对象进行编辑.

如果您需要的是完全双向支持(检索以及插入、更新和删除功能),那么您实际上仅限于使用完全实体类。

编辑这是使用“lite”实体的示例:

考虑我们有一个Customer在我们的上下文中命名的实体。我们需要一个仅包含 ID (an int) 和名称 (a string) 的 lite 客户。只需为 lite 实体定义一个类:

public class CustomerLite
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
}

然后在这样的查询中使用它:

var liteCustomers = context.Customers
                    .Where(c => c.Name.StartsWith("Smith, ")
                    .Select(c => new CustomerLite()
                    {
                        CustomerId = c.CustomerId,
                        Name = c.Name
                    })
                    .ToList();

(或者,如果您更喜欢查询语法而不是 lambda 语法)

var liteCustomers = (from c in context.Customers
                     where c.Name.StartsWith("Smith, ")
                     select new CustomerLite()
                     {
                         CustomerId = c.CustomerId,
                         Name = c.Name
                     }).ToList();
于 2013-03-25T19:22:14.357 回答
2

是的,这是一个很好的方法。如果您想直接从数据库中将其作为查询返回,那么这是要走的路。

另一种方法是使用接口:

public interface ISmallEmployee
{
    string attr1 {get;set;} //same as BigEmployee attr1
    string attr2 {get;set;} //same as BigEmployee attr2
    string attr3 {get;set;} //same as BigEmployee attr3
}

public class BigEmployee : ISmallEmployee
{
    ...
}

但是,ORM 可能不会直接识别这一点,因此您必须查询 allBigEmployee并将它们转换ISmallEmployee为 C#。

你也可以创建SmallEmployee一个基类BigEmployee,你需要注意如何配置你的 ORM 来解释这个。

于 2013-03-25T19:18:24.583 回答
0

我认为你在正确的轨道上。

在 SOLID http://www.codeproject.com/Articles/60845/The-SOLID-Object-Oriented-Programming-OOP-Prin中查找 I

在这种情况下,将您的主要对象映射到您的客户需要的任何投影。

于 2013-03-25T19:24:05.910 回答