Alrighty,
So here I am without sleep for 2 days and I still can't figure this out. So I'm back to beg for a little help.
So I have a User class, and the user class has a sub class Address which is created as a list Addresses. This allows User to have 1 or 50 different addresses on file.
Due to speed requirements for the system we are saving the addresses in the database as such
User Table:
GUID
TimeStamp
UserAddresses Table:
UserGUID
AddressGUID
FieldID
FieldValue
TimeStamp
So what happens here is that when they save an address, we get a timestamp (unix style 32 bit) which we then update user with, and instead of updating records in UserAddresses we insert all new records (for all fields, not just the edited ones) that have the updated timestamp and a clean up processes goes in and deletes the old records after 90 days (gives us a live history type as well as performance boost).
The problem I am having is that if say someone changes the street, and zipcode for an address, I want to only insert all new records once, not once for each edit.
Any ideas how I do this? I can send a copy of the code if you need.
Thanks!
Andrew
Here is a look at the specific source code in question.
using System;
using System.Collections.Generic;
using Csla;
using Csla.Data;
using Csla.Validation;
using ProjectUnicorn.Library.Utilities;
using System.Data;
using UnicornData;
namespace ProjectUnicorn.Library
{
[Serializable()]
public class User : Csla.BusinessBase<User>
{
#region Properties
//Do we need to have any comments in property declarations?
private string _UserID = "";
private string _UserName = "";
private string _Password = "";
private string _FirstName = "";
private string _LastName = "";
private string _EmailAddress = "";
private SmartDate _BirthDate;
private int _Rolls = 0;
#region Get/Set
public string UserID
{
get { return _UserID; }
set
{
_UserID = value;
PropertyHasChanged("UserID");
}
}
public string UserName
{
get { return _UserName; }
set
{
_UserName = value;
PropertyHasChanged("UserName");
}
}
public string Password
{
get { return _Password; }
set
{
_Password = value;
PropertyHasChanged("Password");
}
}
public string FirstName
{
get { return _FirstName; }
set
{
_FirstName = value;
PropertyHasChanged("FirstName");
}
}
public string LastName
{
get { return _LastName; }
set
{
_LastName = value;
PropertyHasChanged("LastName");
}
}
public string EmailAddress
{
get { return _EmailAddress; }
set
{
_EmailAddress = value;
PropertyHasChanged("EmailAddress");
}
}
public SmartDate BirthDate
{
get { return _BirthDate; }
set
{
_BirthDate = value;
PropertyHasChanged("BirthDate");
}
}
public int Rolls
{
get { return _Rolls; }
set
{
_Rolls = value;
PropertyHasChanged("Rolls");
}
}
#endregion
#endregion
#region Subclasses
[Serializable()]
public class UserAccount : User
{
#region Properties
private string _PhoneNumber = "";
private string _MobileNumber = "";
private List<Address> _addresses = new List<Address>();
#region Get/Set
public string PhoneNumber
{
get { return _PhoneNumber; }
set
{
_PhoneNumber = value;
PropertyHasChanged("PhoneNumber");
}
}
public string MobileNumber
{
get { return _MobileNumber; }
set
{
_MobileNumber = value;
PropertyHasChanged("MobileNumber");
}
}
public List<Address> Addresses
{
get { return _addresses; }
set
{
_addresses = value;
PropertyHasChanged("Addresses");
}
}
public Address getDefaultAddress()
{
foreach (Address addr in _addresses)
{
if (addr.IsDefault)
return addr;
}
return null;
}
#endregion
#endregion
#region Methods
#endregion
#region Addresses
public class Address : UserAccount
{
public override string ToString()
{
string tmp = _address1;
if (_address2 != null)
{
tmp += ("\r\n" + _address2);
}
if (_address3 != null)
{
tmp += ("\r\n" + _address3);
} tmp += ("\r\n" + _city);
tmp += (", " + _state);
tmp += (" " + _zipcode);
tmp += ("\r\nIs Default: " + _isDefault);
return tmp;
}
#region Address Properties
private string _addressname;
private string _address1;
private string _address2;
private string _address3;
private string _city;
private string _state;
private string _zipcode;
private bool _isDefault = false;
public string AddressName
{
get { return _addressname; }
}
public string Address1
{
get { return _address1; }
set
{
_address1 = value;
PropertyHasChanged("Address1");
}
}
public string Address2
{
get { return _address2; }
set
{
_address2 = value;
PropertyHasChanged("Address2");
}
}
public string Address3
{
get { return _address3; }
set
{
_address3 = value;
PropertyHasChanged("Address3");
}
}
public string City
{
get { return _city; }
set
{
_city = value;
PropertyHasChanged("City");
}
}
public string State
{
get { return _state; }
set
{
_state = value;
PropertyHasChanged("State");
}
}
public string Zipcode
{
get { return _zipcode; }
set
{
_zipcode = value;
PropertyHasChanged("Zipcode");
}
}
public bool IsDefault
{
get { return _isDefault; }
set
{
_isDefault = value;
PropertyHasChanged("IsDefaultAddress");
}
}
#endregion Address Properties
}
#endregion Addresses
}
#region Business Methods
/*
* The Business Methods region will contain the methods that are used by
* UI code (or other client-level code) to interact with the business
* object. This includes any properties that allow retrieval or changing
* of values in the object, as well as methods that operate on the object's
* data to perform business processing.
*/
private int _id = 0;
private byte[] _timestamp = new byte;
[System.ComponentModel.DataObjectField(true, true)]
public int Id
{
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
get
{
CanReadProperty(true);
return _id;
}
}
public override bool IsValid
{
get { return base.IsValid; }
// If this object contains child objects, then:
// get { return base.IsValid && [child object].IsValid; }
}
public override bool IsDirty
{
get { return base.IsDirty; }
// If this object contains child objects, then:
// get { return base.IsDirty || _assignments.IsDirty; }
}
protected override object GetIdValue()
{
return _id;
}
public bool CreateAccount(string strUserName, string strPassword, string strEmailAddress, SmartDate dtDateOfBirth, int intRoles)
{
return true;
}
public bool CheckUsernameAvailability(string strUserName)
{
DataView tmpReturnedData;
DataTools.UserData tmpData = new DataTools.UserData();
tmpReturnedData = new DataView();
tmpReturnedData.Table = tmpData.GetUserByUserName(strUserName).Tables["users"];
if (tmpReturnedData.Table.Rows.Count == 0)
{
return true;
}
else
{
return false;
}
}
public bool CheckEmailAddressAvailability(string strEmailAddress)
{
DataView tmpReturnedData;
DataTools.UserData tmpData = new DataTools.UserData();
tmpReturnedData = new DataView();
tmpReturnedData.Table = tmpData.GetUserByEmailAddress(strEmailAddress).Tables["users"];
if (tmpReturnedData.Table.Rows.Count == 0)
{
return true;
}
else
{
return false;
}
}
public void DisableAccount(long UserID, string strReason)
{
}
public bool UpdateAccount()
{
return true;
}
#endregion
#region Validation Rules
/*
* The Validation Rules region will contain the AddBusinessRules() method, and
* any custom rule methods required by the object.
*/
protected override void AddBusinessRules()
{
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("Address1", 50));
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("Address2", 50));
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("Address3", 50));
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("City", 30));
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("State", 30));
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("Zipcode", 10));
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("FirstName", 30));
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("LastName", 30));
ValidationRules.AddRule(new RuleHandler(CommonRules.StringMaxLength),
new CommonRules.MaxLengthRuleArgs("EmailAddress", 100));
}
#endregion
#region Authorization Rules
/*
* The Authorization Rules region will contain the AddAuthorizationRules() method.
* It will also contain a standard set of static methods indicating whether the
* current user is authorizaed to get, add, save, or delete this type of business
* object.
*/
protected override void AddAuthorizationRules()
{
// AuthorizationRules.AllowWrite();
}
public static bool CanAddObject()
{
bool result = false;
return result;
}
public static bool CanGetObject()
{
bool result = true;
return result;
}
public static bool CanDeleteObject()
{
bool result = false;
return result;
}
public static bool CanEditObject()
{
bool result = false;
return result;
}
#endregion
#region Factory Methods
/*
* The Factory Methods region will contain the static factory methods to create or
* retrieve the object, along with the static delete method (if the object is
* editable. It will also contain the default constructor for the class, which must
* be scoped as non-public (i.e. private or protected) to force the use of the factory
* methods when creating the business object.
*/
public static User NewUser()
{
if (!CanAddObject())
throw new System.Security.SecurityException(
"User not authorized to add a user");
return DataPortal.Create<User>();
}
public static void DeleteUser(int id)
{
if (!CanDeleteObject())
throw new System.Security.SecurityException(
"User not authorized to remove a user");
DataPortal.Delete(new Criteria(id));
}
public static User GetUser(int id)
{
if (!CanGetObject())
throw new System.Security.SecurityException(
"User not authorized to view a user");
return DataPortal.Fetch<User>(new Criteria(id));
}
public override User Save()
{
if (IsDeleted && !CanDeleteObject())
throw new System.Security.SecurityException(
"User not authorized to remove a user");
else if (IsNew && !CanAddObject())
throw new System.Security.SecurityException(
"User not authorized to add a user");
else if (!CanEditObject())
throw new System.Security.SecurityException(
"User not authorized to update a user");
return base.Save();
}
protected User()
{
}
#endregion
#region Data Access
/*
* The Data Access region will contain the DataPortal_* methods. It will also contain
* the Criteria class used to create, retrieve, or delete the object.
*/
[Serializable()]
private class Criteria
{
private int _id;
public int Id
{
get { return _id; }
}
public Criteria(int id)
{ _id = id; }
}
// Use [RunLocal()] for objects that do not need to get populated with default data from the DB
[RunLocal()]
protected override void DataPortal_Create()
{
// nothing to initialize
ValidationRules.CheckRules();
}
private void DataPortal_Fetch(Criteria criteria)
{
}
protected override void DataPortal_Insert()
{
}
protected override void DataPortal_Update()
{
}
protected override void DataPortal_DeleteSelf()
{
DataPortal_Delete(new Criteria(_id));
}
private void DataPortal_Delete(Criteria criteria)
{
}
protected override void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
{
}
#endregion
#region Exists
/*
* The Exists region will contain static methods to determine whether a specific instance
* of the business object exists.
*/
public static bool Exists(string id)
{
return ExistsCommand.Exists(id);
}
[Serializable()]
private class ExistsCommand : CommandBase
{
private string _id;
private bool _exists;
public bool ResourceExists
{
get { return _exists; }
}
public static bool Exists(string id)
{
ExistsCommand result;
result = DataPortal.Execute<ExistsCommand>(new ExistsCommand(id));
return result.ResourceExists;
}
private ExistsCommand(string id)
{
_id = id;
}
protected override void DataPortal_Execute()
{
_exists = false;
}
}
#endregion
}
}
Copyright (c) Marimer LLC