tchimev posted on Tuesday, January 06, 2009
I have a Linq2Sql DataContext which I re-use in my business objects using CSLA's ContextManager class.
First I call DataPortal_Fetch to get an entity from the DataContext.
Then I transfer values from entity into my business base object's properties.
When I call Save() on the business base object it must be serialized/deserialized so I cannot keep pointer to the Linq2Sql entity.
I have to generate a new linq2sql entity from the business base object's properties and Attach it to the same DataContext during Save(),
I get an error: "Cannot attach an entity with a key that is already in use."
Is there a workaround for this error?
static void Main()
{
using (var db = ContextManager<DB.DefaultDataContext>.GetManager(
Properties.Settings.Default.DefaultConnectionString, false))
{
BO.User user = BO.User.GetUser(17);
user.Name += "A";
user = user.Save();
}
}
[Serializable()]
public class User : BusinessBase<User>
{
private static PropertyInfo<int> _id =
RegisterProperty<int>(new PropertyInfo<int>("ID"));
public int ID
{ get { return GetProperty<int>(_id); } }
private static PropertyInfo<string> _name =
RegisterProperty<string>(new PropertyInfo<string>("Name"));
public string Name
{
get { return GetProperty<string>(_name); }
set { SetProperty<string>(_name, value); }
}
private byte[] _timeStamp = new byte
;
public static User GetUser(int id)
{
return DataPortal.Fetch<User>(new Criteria() { IdField = id });
}
private User() {}
[Serializable()]
private class Criteria { public int IdField = 0; }
protected override void DataPortal_Fetch(object criteria)
{
using (var db = ContextManager<DB.DefaultDataContext>.GetManager(
Properties.Settings.Default.DefaultConnectionString, false))
{
DB.User dbUser = (from us in db.DataContext.Users
where us.ID == ((Criteria)criteria).IdField
select us).SingleOrDefault();
LoadProperty<int>(_id, dbUser.ID);
LoadProperty<string>(_name, dbUser.Name);
this._timeStamp = dbUser.TimeStamp.ToArray();
}
}
protected override void DataPortal_Update()
{
using (var db = ContextManager<DB.DefaultDataContext>.GetManager(
Properties.Settings.Default.DefaultConnectionString, false))
{
DB.User dbUser = new DB.User()
{
ID = ReadProperty<int>(_id),
Name = ReadProperty<string>(_name),
Barcode = "",
TimeStamp = this._timeStamp
};
db.DataContext.Users.Attach(dbUser, this.IsSelfDirty);
db.DataContext.SubmitChanges();
this._timeStamp = dbUser.TimeStamp.ToArray();
}
}
}