2009-01-18 109 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

一般也有很多很好的答案的那展示獨特的數據訪問和業務邏輯層。我要補充的一件事就是擺脫每個班級的接口。當你知道確實只有一個類實現它時編寫一個接口就是過度設計並且不必要地使事情複雜化。現在,如果你正在寫一個類庫,並且只提供一個類作爲模板或其他的起點,那麼情況就不一樣了。但是這裏顯示的界面並沒有爲重新解釋留下很大的空間。