只使用类的一些属性来处理的正确方法是什么?

时间:2013-03-25 19:15:20

标签: c#

我正在添加一个相当大的程序。在此程序中,有一个从我们的数据库映射的类,其中包含每个员工的所有属性。它有姓名,电话号码,雇用日期等等;共有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;
}

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

3 个答案:

答案 0 :(得分:5)

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

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

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

它们仅适用于只读用途

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

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

编辑以下是使用“精简版”实体的示例:

考虑我们在上下文中有一个名为Customer的实体。我们需要一个仅包含ID(int)和名称(string)的精简客户。只需为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();

答案 1 :(得分: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可能无法直接识别,因此您必须查询所有BigEmployee并将其转换为C#中的ISmallEmployee

你也可以使SmallEmployee成为BigEmployee的基类,你需要在如何配置你的ORM来介入这个问题时要小心。

答案 2 :(得分:0)

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

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

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