我应该如何在类和应用程序层之间传递数据?

时间:2010-03-05 14:24:49

标签: c# asp.net

例如,如果我正在创建3层应用程序(数据/业务/ UI),并且数据层正在抓取单个或多个记录。在发送到业务层之前,我是否将所有内容从数据层转换为通用列表/集合?发送数据表是否可以?将信息发送回数据层怎么样?

如果我使用对象/列表,那么这些是Data或Business层的成员吗?我可以使用相同的对象传递给图层吗?

这是一些伪代码:

具有电子邮件/密码的对象用户

在UI层,用户输入电子邮件/密码。 UI层进行验证,然后我假设创建一个新的对象用户传递给业务层,业务层进行进一步验证并将相同的对象传递给数据层以插入记录。这是对的吗?

我是.NET新手(来自8年以上的ASP VBScript背景)并试图以“正确”的方式加快速度。

8 个答案:

答案 0 :(得分:24)

答案 1 :(得分:13)

一般来说,我认为发送对象而不是数据表会更好。对于对象,每个层都知道它接收的内容(哪些对象具有哪些属性等)。您可以通过对象获得编译时安全性,不会意外拼错属性名称等,并强制两层之间的固有合同。

Joshua还提出了一个很好的观点,通过使用自定义对象,您还可以将其他层与数据层分离。您始终可以从其他数据源填充自定义对象,而其他层将更加明智。使用SQL数据表,这可能不会那么容易。

乔尔也提出了一个很好的观点。让您的数据层了解您的业务对象并不是一个好主意,原因与使您的业务和UI层了解数据层的细节相同。

答案 2 :(得分:7)

与世界上的编程团队一样,有几乎“正确”的方法可以做到这一点。也就是说,喜欢做的是为我的每个业务对象构建一个工厂,看起来像这样:

public static class SomeBusinessObjectFactory
{
   public static SomeBusinessObject FromDataRow(IDataRecord row)
   {
       return new SomeBusinessObject() { Property1 = row["Property1"], Property2 = row["Property2"] ... };
   }
}

我还有一个通用的翻译方法,我用它来称呼这些工厂:

public static IEnumerable<T> TranslateQuery(IEnumerable<IDatarecord> source, Func<IDatarecord, T> Factory)
{
    foreach (IDatarecord item in source)
        yield return Factory(item);
}

根据您的团队喜欢的内容,项目的大小等,这些工厂对象和翻译器可以与业务层或数据层一起使用,甚至可以使用额外的“翻译”程序集/层。

然后我的数据层将包含如下代码:

private SqlConnection GetConnection()
{
    var conn = new SqlConnection( /* connection string loaded from config file */ );
    conn.Open();
    return conn;
}

private static IEnumerable<IDataRecord> ExecuteEnumerable(this SqlCommand command)
{
    using (var rdr = command.ExecuteReader())
    { 
        while (rdr.Read())
        {
            yield return rdr;
        }
    }
}

public  IEnumerable<IDataRecord> SomeQuery(int SomeParameter)
{
    string sql = " .... ";

    using (var cn = GetConnection())
    using (var cmd = new SqlCommand(sql, cn))
    {
        cmd.Parameters.Add("@Someparameter", SqlDbType.Int).Value = SomeParameter;
        return cmd.ExecuteEnumerable();
    }
}

然后我可以像这样把它们放在一起:

 SomeGridControl.DataSource = TranslateQuery(SomeQuery(5), SomeBusinessObjectFactory.FromDataRow);

答案 3 :(得分:1)

我将添加一个新图层 ORM对象关系映射,负责将数据从数据层转换为业务对象集合。我认为在商务模型中使用对象是最佳实践。

答案 4 :(得分:1)

无论您使用什么方法在应用程序的各层之间传递数据,只需确保每个层的实现细节不会泄漏到其他层。您应该能够更改关系数据库中的数据的存储方式,而无需修改业务对象层中的任何代码(当然不是序列化)。

业务对象的设计与关系数据模型之间的紧密耦合极具刺激性,浪费了良好的RDBMS。

答案 5 :(得分:1)

这里有很多很棒的答案,我想补充一点,在你花费大量时间创建翻译层和工厂之前,了解应用程序的目的和未来非常重要。

某处,无论是配置映射文件,工厂,还是直接在您的数据/业务/ ui层,某些对象/文件/类/等都必须知道每层之间发生的事情。如果交换图层是切合实际的,那么创建转换图层很有用。其他时候,让一些层(我通常在业务中)知道所有接口(或者至少足以在数据和ui之间进行代理)是有意义的。

同样,这并不是说所有这些都很糟糕,只是有可能YAGNI。一些DI和ORM框架使这些东西变得如此简单,以至于不这样做是愚蠢的。如果您正在使用它,那么获得所有它的价值可能是有意义的。

答案 6 :(得分:0)

我现在正在处理的应用程序相当陈旧(在.NET术语中),并使用强类型数据集在数据层和业务层之间传递数据。在业务层中,数据集中的数据在传递到前端之前手动“或映射”到业务对象。

这可能不是一个受欢迎的设计决定,因为强类型数据集总是有点争议。

答案 7 :(得分:0)

我强烈建议您使用对象。另一种方式表明,只有接口是公共的,而您的实现是内部的,并且您通过对象的工厂公开您的方法,然后将您的工厂与façade结合,最终为您的库提供一个唯一的入口点。然后,只有数据对象穿过你的外观,所以你总是知道在你的外墙外面会发生什么。

这样,任何用户界面都可以调用你的图书馆的外观,而代码中唯一剩下的就是你的用户界面。

这是一个我个人非常有趣的链接,总结了不同的设计模式:GoF .NET Design Patterns for C# and VBNET

如果您想要一个代码示例来说明我的陈述,请随时提出。