2009-01-18 117 views
1

我是编程新手,所以我想我会从那些知道它的人那里得到帮助。需要课堂设计帮助

我目前正在编写一个注册申请,它基本上会接受用户输入, 验证输入的数据,显示一个评论屏幕(用户必须打印出来并邮寄一份副本),然后将输入的信息保存到一个数据库。

以下是需要捕获和保存的字段。

public class Person 
{ 
    private string id; 
    private string currentLastName; 
    private string currentFirstName; 
    private string currentMiddleName; 
    private string currentSuffixtName; 

    private string formerLastName; 
    private string formerFirstName; 
    private string formerMiddleName; 
    private string formerSuffixtName; 

    private string currentAddressNumber; 
    private string currentAddressDirection; 
    private string currentAddressStreet; 
    private string currentAddressStreetType; 
    private string currentAddressAptNum; 
    private string currentAddressrCity; 
    private string currentAddressState; 
    private string currentAddressZipcode; 
    private string currentAddressCounty; 

    private string formerAddressNumber; 
    private string formerAddressDirection; 
    private string formerAddressStreet; 
    private string formerAddressStreetType; 
    private string formerAddressAptNum; 
    private string formerAddressrCity; 
    private string formerAddressState; 
    private string formerAddressZipcode; 
    private string formerAddressCounty; 

    private string mailAddressLineOne; 
    private string mailAddressLineTwo; 
    private string mailAddressLineThree; 

    private DateTime birthdate; 
    private string gender; 
    private string HomePhone; 
    private string WorkPhone; 
    private string CellPhone; 
    private string FaxNumber; 
    private string driversLicense; 
    private string ssNumber; 
    private string membershipType; 
    private DateTime registrationDate; 
    private string ipAddress; 
    private string browserInfo; 
} 

给这一个又看了一眼后,我想我会走出独立的共同的东西,并为他们每个人的一类,有一个人拥有的每个类或类的接口。即

public interface IName 
{ 
    string getLastName(); 
    string getFirstName(); 
    string getMiddleName(); 
    string getSuffixName(); 
} 

    public class Name : IName 
{ 
    private string _lastName; 
    private string _firstName; 
    private string _middleName; 
    private string _suffixName; 

    // Validation Methods 
    // private set methods 

    //#region IName Members 
} 


public interface IAddress 
{ 
    string getAddressNumber(); 
    string getAddressDirection(); 
    string getAddressStreet(); 
    string getAddressStreetType(); 
    string getAddressAptNum(); 
    string getAddressCity(); 
    string getAddressState(); 
    string getAddressZipcode(); 
    string getAddressCounty(); 
} 

public class Address : IAddress 
{ 
    private string _addressNumber; 
    private string _addressDirection; 
    private string _addressStreet; 
    private string _addressStreetType; 
    private string _addressAptNum; 
    private string _addressrCity; 
    private string _addressState; 
    private string _addressZipcode; 
    private string _addressCounty; 

    // Validation Methods 
    // private Set Methods 
    // public get methods 


    //#region IAddress Members 
} 
public interface IPerson 
{ 
    int getId(); 
    IName getCurrentName(); 
    IName getFormerName(); 

    IAddress getCurrentAddress(); 
    IAddress getFormerAddress(); 
    IAddress getMailingAddress(); 

    DateTime getBirthdate(); 
    string getGender(); 
    string getSSNumber(); 
    string getPersonType(); 
    DateTime getRegistrationDate(); 
    string getIPAddress(); 
    string getBrowserInfo(); 
    string getDriversLicense(); 

    string getHomePhone(); 
    string getWorkPhone(); 
    string getCellPhone(); 
    string getFaxNumber(); 
    string getEmailAddress(); 
    string getSecondaryEmailAddress(); 

    bool save(); 
    void load(); 

} 

public class Person : IPerson 
{ 
    private int _id; 
    private IName _currentName; 
    private IName _formerName; 

    private IAddress _currentAddress; 
    private IAddress _formerAddress; 
    private IAddress _mailingAddress; 

    private DateTime _birthdate; 
    private string _gender; 
    private string _ssNumber; 
    private string _personType; 
    private DateTime _registrationDate; 
    private string _ipAddress; 
    private string _browserInfo; 
    private string _driversLicense; 

    private string _homePhone; 
    private string _workPhone; 
    private string _cellPhone; 
    private string _faxNumber; 
    private string _emailAddress; 
    private string _secondaryEmailAddress; 


    // private set methods 

    // #region IPerson Members 
    // .... Get Methods 
    public bool save() 
    { 
     DataLayer dl = new DataLayer(); 
     if (_id == 0) 
      return dl.insertPerson(this); 
     else 
      return dl.updatePerson(this); 
    } 
} 

这里是我的数据层插入方法

public bool insertPerson(IPerson person) 
{ 
    bool inserted = false; 
    SqlConnection cnDB = DatabaseConnection.GetOpenDBConnection(); 
    try 
    { 
     SqlCommand cmDB = new SqlCommand("sp_InsertName", cnDB); 
     cmDB.CommandType = CommandType.StoredProcedure; 
     cmDB.Parameters.Add("@last_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@last_name"].Value = person.getCurrentName().getLastName(); 
     cmDB.Parameters.Add("@first_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@first_name"].Value = person.getCurrentName().getFirstName(); 
     cmDB.Parameters.Add("@middle_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@middle_name"].Value = person.getCurrentName().getMiddleName(); 
     cmDB.Parameters.Add("@suffix_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@suffix_name"].Value = person.getCurrentName().getSuffixName(); 
     int id = cmDB.ExecuteNonQuery(); 

     cmDB = new SqlCommand("sp_InsertName", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@last_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@last_name"].Value = person.getFormerName().getLastName(); 
     cmDB.Parameters.Add("@former_first_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@former_first_name"].Value = person.getFormerName().getFirstName(); 
     cmDB.Parameters.Add("@middle_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@middle_name"].Value = person.getFormerName().getMiddleName(); 
     cmDB.Parameters.Add("@suffix_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@suffix_name"].Value = person.getFormerName().getSuffixName(); 
     cmDB.ExecuteNonQuery(); 

     // Insert Current Address 

     cmDB = new SqlCommand("sp_InsertAddress", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@address_number", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_number"].Value = person.getCurrentAddress().getAddressNumber(); 
     cmDB.Parameters.Add("@address_direction", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_direction"].Value = person.getCurrentAddress().getAddressDirection(); 
     cmDB.Parameters.Add("@address_street", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_street"].Value = person.getCurrentAddress().getAddressStreet(); 
     cmDB.Parameters.Add("@address_street_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_street_type"].Value = person.getCurrentAddress().getAddressStreetType(); 
     cmDB.Parameters.Add("@address_apt_number", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_apt_number"].Value = person.getCurrentAddress().getAddressAptNum(); 
     cmDB.Parameters.Add("@address_city", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_city"].Value = person.getCurrentAddress().getAddressCity(); 
     cmDB.Parameters.Add("@address_state", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_state"].Value = person.getCurrentAddress().getAddressCity(); 
     cmDB.Parameters.Add("@address_zipcode", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_zipcode"].Value = person.getCurrentAddress().getAddressZipcode(); 
     cmDB.Parameters.Add("@address_county", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_county"].Value = person.getCurrentAddress().getAddressCounty(); 
     cmDB.ExecuteNonQuery(); 

     // Insert Former Address 

     cmDB = new SqlCommand("sp_InsertAddress", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@address_number", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_number"].Value = person.getFormerAddress().getAddressNumber(); 
     cmDB.Parameters.Add("@address_direction", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_direction"].Value = person.getFormerAddress().getAddressDirection(); 
     cmDB.Parameters.Add("@address_street", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_street"].Value = person.getFormerAddress().getAddressStreet(); 
     cmDB.Parameters.Add("@address_street_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_street_type"].Value = person.getFormerAddress().getAddressStreetType(); 
     cmDB.Parameters.Add("@address_apt_number", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_apt_number"].Value = person.getFormerAddress().getAddressAptNum(); 
     cmDB.Parameters.Add("@address_city", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_city"].Value = person.getFormerAddress().getAddressCity(); 
     cmDB.Parameters.Add("@address_state", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_state"].Value = person.getFormerAddress().getAddressCity(); 
     cmDB.Parameters.Add("@address_zipcode", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_zipcode"].Value = person.getFormerAddress().getAddressZipcode(); 
     cmDB.Parameters.Add("@address_county", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_county"].Value = person.getFormerAddress().getAddressCounty(); 
     cmDB.ExecuteNonQuery(); 

     // Insert Mailing Address 

     cmDB = new SqlCommand("sp_InsertAddress", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@address_number", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_number"].Value = person.getMailingAddress().getAddressNumber(); 
     cmDB.Parameters.Add("@address_direction", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_direction"].Value = person.getMailingAddress().getAddressDirection(); 
     cmDB.Parameters.Add("@address_street", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_street"].Value = person.getMailingAddress().getAddressStreet(); 
     cmDB.Parameters.Add("@address_street_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_street_type"].Value = person.getMailingAddress().getAddressStreetType(); 
     cmDB.Parameters.Add("@address_apt_number", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_apt_number"].Value = person.getMailingAddress().getAddressAptNum(); 
     cmDB.Parameters.Add("@address_city", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_city"].Value = person.getMailingAddress().getAddressCity(); 
     cmDB.Parameters.Add("@address_state", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_state"].Value = person.getMailingAddress().getAddressCity(); 
     cmDB.Parameters.Add("@address_zipcode", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_zipcode"].Value = person.getMailingAddress().getAddressZipcode(); 
     cmDB.Parameters.Add("@address_county", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@address_county"].Value = person.getMailingAddress().getAddressCounty(); 
     cmDB.ExecuteNonQuery(); 

     // insert Personal Info 

     cmDB = new SqlCommand("sp_InsertPersonalInfo", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@birthdate", System.Data.SqlDbType.DateTime); 
     cmDB.Parameters["@birthdate"].Value = person.getBirthdate(); 
     cmDB.Parameters.Add("@gender", System.Data.SqlDbType.VarChar, 1); 
     cmDB.Parameters["@gender"].Value = person.getGender(); 
     cmDB.Parameters.Add("@ss_number", System.Data.SqlDbType.VarChar, 20); 
     cmDB.Parameters["@ss_number"].Value = person.getSSNumber(); 
     cmDB.Parameters.Add("@person_type", System.Data.SqlDbType.VarChar, 20); 
     cmDB.Parameters["@person_type"].Value = person.getPersonType(); 
     cmDB.Parameters.Add("@registration_date", System.Data.SqlDbType.DateTime); 
     cmDB.Parameters["@registration_date"].Value = person.getRegistrationDate(); 
     cmDB.Parameters.Add("@ip_address", System.Data.SqlDbType.VarChar, 20); 
     cmDB.Parameters["@ip_address"].Value = person.getIPAddress(); 
     cmDB.Parameters.Add("@browser_info", System.Data.SqlDbType.VarChar, 20); 
     cmDB.Parameters["@browser_info"].Value = person.getBrowserInfo(); 
     cmDB.Parameters.Add("@drivers_license", System.Data.SqlDbType.VarChar, 20); 
     cmDB.Parameters["@drivers_license"].Value = person.getDriversLicense(); 
     cmDB.ExecuteNonQuery(); 

     //insert email address contact type 
     cmDB = new SqlCommand("sp_InsertContactType", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@contact_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact_type"].Value = "Email"; 
     cmDB.Parameters.Add("@contact", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@gender"].Value = person.getEmailAddress(); 
     cmDB.ExecuteNonQuery(); 

     //insert secondary email address contact type 
     cmDB = new SqlCommand("sp_InsertContactType", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@contact_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact_type"].Value = "Secondary Email"; 
     cmDB.Parameters.Add("@contact", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@gender"].Value = person.getSecondaryEmailAddress(); 
     cmDB.ExecuteNonQuery(); 

     //insert home phone contact type 
     cmDB = new SqlCommand("sp_InsertContactType", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@contact_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact_type"].Value = "Home Phone"; 
     cmDB.Parameters.Add("@contact", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact"].Value = person.getHomePhone(); 
     cmDB.ExecuteNonQuery(); 

     //insert work phone contact type 
     cmDB = new SqlCommand("sp_InsertContactType", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@contact_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact_type"].Value = "Work Phone"; 
     cmDB.Parameters.Add("@contact", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact"].Value = person.getWorkPhone(); 
     cmDB.ExecuteNonQuery(); 

     //insert cell phone contact type 
     cmDB = new SqlCommand("sp_InsertContactType", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@contact_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact_type"].Value = "Cell Phone"; 
     cmDB.Parameters.Add("@contact", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact"].Value = person.getCellPhone(); 
     cmDB.ExecuteNonQuery(); 

     //insert cell phone contact type 
     cmDB = new SqlCommand("sp_InsertContactType", cnDB); 
     cmDB.Parameters.Add("@person_id", System.Data.SqlDbType.Int); 
     cmDB.Parameters["@person_id"].Value = id; 
     cmDB.Parameters.Add("@contact_type", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact_type"].Value = "Fax Number"; 
     cmDB.Parameters.Add("@contact", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@contact"].Value = person.getFaxNumber(); 
     cmDB.ExecuteNonQuery(); 


     inserted = true; 
    } 
    catch (SqlException sqlEx) 
    { 
     throw new Exception(GetSqlExceptionMessage(sqlEx.Number)); 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
    finally 
    { 
     if (cnDB.State == ConnectionState.Open) 
      cnDB.Close(); 
    } 
    return inserted; 
} 

编辑:我觉得这个代码将是非常难以维持以后。 任何人都可以帮助我找出一个更简单/可维护的方法来做到这一点? 我也难住我应该如何在添加记录后更新记录。

预先感谢任何帮助

+0

虽然会员提供商解决了这个问题,但仍然很高兴看到一些帖子提出了改进建议,而不管OP作为学习体验。 – 2009-03-23 21:17:21

回答

3

首先,如果你想简化维护,我会看看使用ORM来做映射。我会看nHibernate,Linq2Sql,实体框架或其他十亿左右的其中之一。它会从上面消除很多噪音。

第二个建议是继续进行重构。我喜欢你如何吸引人的地址,如果你看看你的人,一个人没有以前的名字,你的行为是在你的领域模型中泄露一个跟踪以前信息的要求。我将所有的说了出来,并定义一个DTO,这将有两个属性:

public class PersonDTO 
{ 
    public Person Current; 
    Public Person Previous; 
} 

我认为这清除了大量的噪音。我也喜欢使用字典来处理多个电话号码主要有:

public class Phone 
{ 
    PhoneType PhoneType; 
    string Number 
    string AreaCode 
    string Extension 
} 

有些人可能使手机有数字,所以我不想争论说,或者你可以只是一个字符串如你做。有一点要记住的是国际化,如果这适用。

现在在我的人身上我会有一个字典,这样你就可以在你循环使用电话字典时将你的四个插入分成一个循环。如果您有账单或发货地址,我会使用simillar模式。

如果你不使用ORM,那么有一种方法可以帮助坚持使用你的SQL参数DRY很简单。下面的代码并不意味着编译只是向您展示的模式再次减少噪音:

public class DALLayer 
{ 
    public void InsertPerson(Person p) 
    { 
     using (SqlCommand sqlCmd=CreateNewCommand()) 
     { 
      AddPersonParams(p,sqlCmd); 
      sqlCmd.ExecuteNonQuery(); 
     } 
    } 

    public void UpdatePerson(Person p) 
    { 
     using (SqlCommand sqlCmd=CreateNewCommand()) 
     { 
      AddPersonParams(p,sqlCmd); 
      //We add the Id since we have it in updates but not in inserts 
      sqlCmd.AddParameter("@PersonId",p.Id); 
      sqlCmd.ExecuteNonQuery(); 
     } 

    } 

    private void AddPersonParams(Person p, Sqlcommand sqlCmd) 
    { 
     //Do all the code to add Params which exists in both insert and updates 
    } 

} 

现在你所做的事得到巩固,所以当你添加一个新的属性,一个人,你只需要处理参数时修改一个函数。

还有一件事要插入你当前和以前的地址,你不是干的。如果你采纳我前面的建议,这可能看起来非常不同

InsertAddress(p.CurrentAddress,id,CurrentAddress); 
InsertAddress(p.FormerAddress,id,FormerAddress); 

当然:你可以这样做:

private void InserAddress(Address address, int Id, AddressType addType) 
{ 

} 

现在从您的插入人的常规,你会两次调用此方法。

编辑

我完全错过了这一点,但我想强调什么克里斯说(我+ 1你,但认为这是这样的好事,我不得不再说一遍。使用特性:-)

1

我注意到使用ASP.NET你的,你应该知道,成员资格提供能处理所有琐碎的工作中为您服务。

+0

尽管内置提供程序可以提供帮助,但它不会处理完整场景 - 请参阅http://msdn.microsoft.com/en-us/library/aa478949.aspx#data_schema获取其保存的信息。当然,您可以编写自定义提供程序,但是您也可以得到同样的结果,即如何构建zSysop方案。 – eglasius 2009-03-24 17:35:01

0

我很好奇你将如何处理将来的更新到一个人的地址等。而不是合并当前和以前的元素到一个对象,你可能想考虑一个审计跟踪表。让您的Person对象只包含一组数据。查询当前数据的实际表,并根据审计表查询以前和“上一个”的数据。除非出于某种奇怪的原因,否则软件需求会要求先前的名字等,以预先创建人员。

+0

软件要求规定,如果输入的人有以前的姓名或以前的地址,则必须在搜索或打印作业时捕获并显示该地址。 我们有一个历史记录数据库,可以在输入记录之后捕获记录的变化,但是这是审计追踪的目的。 – zSynopsis 2009-03-24 03:42:25

2

根据您列出的要求,您似乎不需要对应用程序中的数据进行大量操作。特别地,看起来这些中的一些看起来可以被视为与用户相关联的数据列表,即名称,地址和电话的列表。您发布的数据访问代码似乎已经以这种方式构建,我认为在您的情况下,您有必要使应用程序的逻辑端更加严格。

鉴于名称被视为与人员相关的数据列表,我不认为您想要创建用户的第一个插入片段。您可以将其他信息添加到主记录中,例如driversLicense,ssn,birthdate。

对于接口,请考虑是否有任何问题。这是打破类之间直接依赖关系的好方法,但它看起来并没有在代码中拥有这种情况。另请注意,声明接口不会强制您使用get/set方法,因为您可以要求带有get的属性由类实现。

为列表中使用的每个类添加一个type属性。您可以使用它来减少接口和数据访问层中的代码。在后面,您现在可以循环访问列表并以相同的方式插入所有这些。

考虑使用可以帮助您访问数据的东西,比如linq2sql或nhibernate。这将简化数据访问代码并使其不易出错。

诗篇。对于所有情景都没有单一解决方案,甚至在特定情景下,个人经验也会影响每个人解决问题的方式。有一些实践和原则旨在减少这种情况,但即使这样也会出现差异。也就是说,我建议你阅读关于SOLID,DDD和TDD的一些信息。他们不是这些问题的秘诀,但了解这些问题肯定有助于软件开发。

更新:关于评论中的问题。 Linq2sql支持存储过程,请在linq2sql上检查scott gu的系列:http://weblogs.asp.net/scottgu/archive/2007/09/07/linq-to-sql-part-9-using-a-custom-linq-expression-with-the-lt-asp-linqdatasource-gt-control.aspx。通过使用sp,你失去了linq2sql灵活性的一部分,但无论如何它都会帮助你。

关于更新。有不同的策略,主要问题是关于对同一信息的并发更新。如果并发更新不是问题,那么您可以保留最新版本,以便保存数据。在这种情况下,您需要的唯一原始数据是记录的ID,并让数据被覆盖。如果您需要检测并发更新,则必须保留所有原始值的副本或使用时间戳。更新记录时,sp代码需要检查匹配的原始值。

您可以在设计器中配置linq2sql以控制您使用的并发更新策略类型以及您要发送的原始值。与此有关的SO可能有一些问题/答案。你如何专门连接它,将取决于你使用它的用途(使用它生成的实体或滚动你自己,将sp附加到实体或单独),甚至你使用的控件,因为它们中的一些可以保存原始值你(使用viewstate)。

+0

感谢您的帮助。 我会将地址/联系人类型/名称移到列表中。 linq2Sql是否适用于存储过程? 原因我可以用来访问数据的是存储过程。 这些记录也可以搜索/更新。 你有什么提示我应该如何解决这个问题? – zSynopsis 2009-03-24 18:26:35

+0

@zSysop添加了一个更新,我建议你看一下linq2sql系列,并考虑它是如何适合你想要实现的。做一些工作,并搜索有关可能出现的更具体问题的信息(当然,如果没有信息,您可以发布进一步的问题)。 – eglasius 2009-03-24 18:58:59

+0

Upvoted因为关于接口的评论...我们需要更多的开发人员批判性地思考和评估一个“最佳实践”,因为它对特定情况的真正好处...这种情况不会使用接口来使用名称,地址和人(至少对我)。 YAGNI。 – 2009-03-27 02:01:44

0

对不起,我不会为你在这里有一个完整的解决方案(只是想开始)。

我真的推荐使用某种生成的数据访问层;例如。 Linq到SQL或NHibernate(还有更多,但这两个都很受欢迎)。您所说的代码很难维护,因为您确实不应该维护代码。让其他人在那里做那些粗野的工作。另外,我会说你将所有的数据分成实现接口的独立类都是正确的。有一点我会提到,但.Net你不需要明确的“getxxxx()”方法;与公共获得者一起使用财产。它看起来像这样:

public class Name : IName 
{ 
    private string _lastName; 
    private string _firstName; 
    private string _middleName; 
    private string _suffixName; 

    public string LastName { get { return _lastName; } } 

    //Alternative automatic property: 
    public string FirstName { get; protected set; } 
} 
1

我希望人员记录具有子表的外键(名称,地址,联系信息等)。

然后,我有一个普通的旧对象,每个字段的属性和一个存储库类负责将类映射到数据库存储过程参数。

我没有填写所有的字段,但应该有足够的空间让你走。此外,你可以提取每个类的接口来编程(用于测试,嘲笑等)。

决定是否保存应插入或更新将涉及编写的UDPATE语句,然后做

public void Save() 
{ 
    string.IsNullOrEmpty(Id) ? Insert() : Update(); 
} 

荡涤数据类:

using System; 
public class PersonName 
{ 
    public string Id { get; set; } 

    public string Last { get; set; } 
    public string First{ get; set; } 
    public string Middle{ get; set; } 
    public string Suffix { get; set; } 
} 

public class PersonNameRepository 
{ 
    public void Insert(PersonName pa) 
    { 
     SqlCommand cmDB = new SqlCommand("sp_InsertName", cnDB); 
     cmDB.CommandType = CommandType.StoredProcedure; 
     cmDB.Parameters.Add("@last_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@last_name"].Value = pa.Last; 
     cmDB.Parameters.Add("@first_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@first_name"].Value = pa.First; 
     cmDB.Parameters.Add("@middle_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@middle_name"].Value = pa.Middle; 
     cmDB.Parameters.Add("@suffix_name", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@suffix_name"].Value = pa.Suffix; 
     int id = cmDB.ExecuteNonQuery(); 
     pa.Id = id.ToString(); 
    } 
} 

public class PersonAddress 
{ 
    public string Id { get; set; } 

    public string Number { get; set; } 
    public string Direction { get; set; } 
    public string Street { get; set; } 
    public string City { get; set; } 
} 

public class PersonAddressRepository 
{ 
    public void Insert(PersonAddress pa) 
    { 
     // Same as PersonNameRepository 
    } 
} 


public class PersonInfo 
{ 
    public string Id { get; set; } 

    public DateTime BirthDate { get; set; } 
    public string Gender { get; set; } 
    public string SsNumber { get; set; } 

} 

public class PersonInfoRepository 
{ 
    public void Insert(PersonInfo pa) 
    { 
     // Same as PersonNameRepository 
    } 
} 
public class Person 
{ 
    public string Id { get; set; } 
    public PersonName CurrentName { get; set; } 
    public PersonName FormerName { get; set; } 

    public PersonAddress CurrentAddress { get; set; } 
    public PersonAddress FormerAddress { get; set; } 

    public PersonInfo Info { get; set; } 
} 

public class PersonRepository 
{ 
    public void Insert(Person p) 
    { 
     // TODO: Begin Transaction 

     p.CurrentName.Insert(); 
     p.FormerName.Insert(); 
     p.CurrentAddress.Insert(); 
     p.FormerAddress.Insert(); 
     p.Info.Insert(); 

     SqlCommand cmDB = new SqlCommand("sp_InsertPerson", cnDB); 
     cmDB.CommandType = CommandType.StoredProcedure; 
     cmDB.Parameters.Add("@current_name_id", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@current_name_id"].Value = p.CurrentName.Id; 
     cmDB.Parameters.Add("@former_name_id", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@former_name_id"].Value = p.FormerName.Id; ; 
     cmDB.Parameters.Add("@current_address_id", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@current_address_id"].Value = p.CurrentAddress.Id; 
     cmDB.Parameters.Add("@former_address_id", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@former_address_id"].Value = p.FormerAddress.Id; 
     cmDB.Parameters.Add("@info_id", System.Data.SqlDbType.VarChar, 50); 
     cmDB.Parameters["@info_id"].Value = p.Info.Id; 
     int id = cmDB.ExecuteNonQuery(); 
     pa.Id = id.ToString(); 

     // TODO: End Transaction 
    } 

} 
0

一般也有很多很好的答案的那展示独特的数据访问和业务逻辑层。我要补充的一件事就是摆脱每个班级的接口。当你知道确实只有一个类实现它时编写一个接口就是过度设计并且不必要地使事情复杂化。现在,如果你正在写一个类库,并且只提供一个类作为模板或其他的起点,那么情况就不一样了。但是这里显示的界面并没有为重新解释留下很大的空间。