在企业应用程序中使用C# XSD类型数据集的最佳实践

6
我正在尝试理解使用当前数据库模式生成的XSD表的最佳实践。
1) 你认为XSD信息应该作为模型的一部分吗?
2) 这是否意味着数据访问层返回数据集和其他生成的对象?
3) 它是否穿过所有系统层一直到UI层?
4) 如果XSD是数据访问层的一部分,我应该将结果从模型转换为对象吗?最佳转换方法是什么?
谢谢, Ronny
1个回答

7
您在问题中将XSD限定为特定于数据集,从而限制了XSD的目的和应用。
XSD是可扩展模式定义的缩写。W3C定义了XSD标准,以标准化您可以在应用程序中使用的XML文件。
例如,假设您在应用程序中大量使用XML文件,并且可能与不同类型的远程源交换这些文件。这些来源可能以各种格式向您发送XML文件。在应用程序中,您需要确保以正确的格式接收XML文件,以便可以进一步对XML文件执行业务操作。因此,您需要对这些XML文件进行标准化。您需要针对可接受的标准验证XML文件。您需要将XML的架构与标准进行比较。这些标准以XSD形式编写。您将根据XSD文件中定义的模式标准验证您的XML文件的模式。这是XSD文件的实际目的。
现在回答您的问题..
1.) 您认为XSD信息是否应作为模型的一部分?
正如我刚才所说的,XSD文件存储模式而不是数据。同样,在任何应用程序中,当您使用数据集时,它实际上会在运行时在内存中保存数据,并且还将具有其自己的模式,以便保存数据的形式。这些基于底层数据表及其关系而异。因此,微软引入了TypedDataSets的概念。正如名称所示,TypedDataSets是您在运行时要使用来处理数据的数据集的合格模式。因此,TypedDataSets实际上以XSD文件的形式定义,该文件定义了DataTable的模式和之间的关系。因此,当您在Visual Studio中创建TypedDataSet文件时,它基本上会创建一个XSD文件,从数据库源添加到TypedDataSet表面的所有表将被分析,并且每个表的元数据模式将在XSD文件中创建。在运行时,当您选择记录到数据集中时,您已经知道正在输入哪种类型的数据,如果数据的形式与XSD中定义的形式不同,则会收到运行时异常。

尽管如此,XSD在运行时并不起作用,因为Visual Studio使用XSD.exe工具从XSD文件生成类型化数据集代码库。

2) 这是否意味着数据访问层返回数据集和其他生成的对象?

如果您的数据层使用了TypedDataset,则会返回DataTable或DataRow[],或者按您所需的方式返回DataRow。

3) 它是否通过所有系统层一直到UI?

您可以在其上生成自定义业务对象,这是一个推荐的做法,而不是在应用程序中随处抛出Dataset对象。

4) 如果XSD是数据访问层的一部分,我应该将结果从模型转换为对象吗?最好的转换方法是什么?

编写一个使用反射的映射机制。我们将DataRow映射到业务对象实例,将DataTables映射到业务对象集合。

您可以开始重新设计,提升您的项目,并采用更易于维护的架构。当然,这需要时间和精力,但最终会有很好的结果。
以下是我的项目内容:
1.) 应用程序基础结构
  • 所有业务对象、业务对象集合、数据访问类和我的自定义属性以及作为扩展方法的实用程序的基类,通用验证框架。这确定了我最终 .net 应用程序的整体行为组织。
2.) 应用程序数据模型
  • 数据库的 XSD 类型数据集。
  • TableAdapters 扩展,以包含事务和其他我可能需要的功能。
3.) 应用程序数据访问
  • 数据访问类。
  • 实际上是使用底层类型化数据集查询数据库操作的地方。
4.) 应用程序领域对象
  • 业务对象和业务对象集合。
  • 枚举。
5.) 应用程序业务层
  • 提供从Presentation层访问的管理类。
  • HttpHandlers。
  • 我的自定义Page基类。
  • 更多内容在这里...

6.) Application.WebClientApplication.WindowsClient

  • 我的Presentation层
  • 引用了Application.BusinessLayer和Application.BusinessObjects。

Application.BusinessObjects在整个应用程序中都被使用,并且在需要时穿越所有层[除了Application.DataModel和Application.Infrastructure]。

我所有的查询都只在Application.DataModel中定义。

Application.DataAccess在任何数据访问操作中返回或接受Business对象。 Business对象是通过反射属性创建的。每个Business对象都带有一个映射到目标数据库表的属性,并且Business对象中的属性都带有映射到相应数据库表中目标列的属性。

我的验证框架可以让我使用指定的ValidationAttribute验证每个字段。

我的框架大量使用属性来自动化大部分繁琐的任务,如映射和验证。我也可以将新功能作为框架中的新方面。

在我的应用程序中,样本Business对象看起来像这样。

User.cs

[TableMapping("Users")]
public class User : EntityBase
{
    #region Constructor(s)
    public AppUser()
    {
        BookCollection = new BookCollection();
    }
    #endregion

    #region Properties

    #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute

    private System.Int32 _UserId;

    private System.String _FirstName;
    private System.String _LastName;
    private System.String _UserName;
    private System.Boolean _IsActive;

    [DataFieldMapping("UserID")]
    [DataObjectFieldAttribute(true, true, false)]
    [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
    public override int Id
    {
        get
        {
            return _UserId;
        }
        set
        {
            _UserId = value;
        }
    }

    [DataFieldMapping("UserName")]
    [Searchable]
    [NotNullOrEmpty(Message = "Username Is Required.")]
    public string UserName
    {
        get
        {
            return _UserName;
        }
        set
        {
            _UserName = value;
        }
    }

    [DataFieldMapping("FirstName")]
    [Searchable]
    public string FirstName
    {
        get
        {
            return _FirstName;
        }
        set
        {
            _FirstName = value;
        }
    }

    [DataFieldMapping("LastName")]
    [Searchable]
    public string LastName
    {
        get
        {
            return _LastName;
        }
        set
        {
            _LastName = value;
        }
    }

    [DataFieldMapping("IsActive")]
    public bool IsActive
    {
        get
        {
            return _IsActive;
        }
        set
        {
            _IsActive = value;
        }
    }

    #region One-To-Many Mappings
    public BookCollection Books { get; set; }

    #endregion

    #region Derived Properties
    public string FullName { get { return this.FirstName + " " + this.LastName; } }

    #endregion

    #endregion

    public override bool Validate()
    {
        bool baseValid = base.Validate();
        bool localValid = Books.Validate();
        return baseValid && localValid;
    }
}

BookCollection.cs

/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection()
    {
    }

    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection (IList<Book> initialList)
        : base(initialList)
    {
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接