DataPortal.Fetch failed (Invalid operation - fetch not allowed)

DataPortal.Fetch failed (Invalid operation - fetch not allowed)

Old forum URL: forums.lhotka.net/forums/t/4093.aspx


ataylorm posted on Wednesday, December 26, 2007

Ugg...  So I am getting this error message when trying to create an instance of my child class by calling:

UserAccount tmpAccount = UserAccount.GetUserAccountByUserID(tmpUser.UserID);

Any ideas what I have wrong in my child class?

THANKS!!!!!

 

 

[Serializable()]

public class UserAccount : Csla.BusinessBase<UserAccount>

{

private string _id;

private string _PhoneNumber;

private string _MobileNumber;

 

public string id

{

get

{

CanReadProperty(true);

return _id;

}

set

{

if (_id != value)

{

_id = value;

PropertyHasChanged("id");

}

}

}

public string PhoneNumber

{

get

{

CanReadProperty(true);

return _PhoneNumber;

}

set

{

_PhoneNumber = value;

PropertyHasChanged("PhoneNumber");

}

}

public string MobileNumber

{

get

{

CanReadProperty(true);

return _MobileNumber;

}

set

{

_MobileNumber = value;

PropertyHasChanged("MobileNumber");

}

}

 

 

#region Business Methods

public string Tester()

{

return "tester";

}

 

protected override object GetIdValue()

{

return _id;

}

#endregion

#region Validation Rules

protected override void AddBusinessRules()

{

// ValidationRules.AddRule<Role>(NoDuplicates, "Id");

// ValidationRules.AddRule(

// Csla.Validation.CommonRules.StringRequired, "Name");

}

// private static bool NoDuplicates<T>(T target, Csla.Validation.RuleArgs e) where T: Role

// {

// Roles parent = (Roles)target.Parent;

// if (parent != null)

// {

// foreach (Role item in parent)

// if (item.Id == target._id && !ReferenceEquals(item, target))

// {

// e.Description = "Role Id must be unique";

// return false;

// }

// }

// return true;

// }

#endregion

#region Authorization Rules

protected override void AddAuthorizationRules()

{

// AuthorizationRules.AllowWrite(

// "Id", "Administrator");

// AuthorizationRules.AllowWrite(

// "Name", "Administrator");

}

#endregion

#region Factory Methods

 

public static UserAccount GetUserAccountByUserID(string id)

{

return DataPortal.Fetch<UserAccount>(id);

}

internal static UserAccount NewUserAccount()

{

return DataPortal.Create<UserAccount>();

}

internal static UserAccount GetUserAccount(string id)

{

return new UserAccount(id);

}

private UserAccount()

{

MarkAsChild();

//ValidationRules.CheckRules();

}

private UserAccount(string id)

{

MarkAsChild();

Fetch(id);

}

#endregion

#region Data Access

private void Fetch(string id)

{

_id = id;

General tmpUtils = new General();

DataTools tmpData = new DataTools();

DataSet tmpDataSet = tmpData.ExecuteDataset(String.Format("SELECT UserAccount.* FROM UserAccount INNER JOIN UserTimeStamps ON UserAccount.TimeStamp = UserTimeStamps.TimeStamp WHERE UserTimeStamps.UserGUID ='{0}' and UserTable = '{1}'", _id, "UserAccount"));

DataView tmpReturnedData;

tmpReturnedData = new DataView();

tmpReturnedData.Table = tmpDataSet.Tables["DataReturned"];

foreach (DataRow d in tmpReturnedData.Table.Rows)

{

switch (d["FieldName"].ToString())

{

case "PhoneNumber":

PhoneNumber = d["FieldValue"].ToString();

break;

case "MobileNumber":

MobileNumber = d["FieldValue"].ToString();

break;

}

}

MarkOld();

}

internal void Insert()

{

// if we're not dirty then don't update the database

if (!this.IsDirty) return;

}

internal void Update()

{

// if we're not dirty then don't update the database.

if (!this.IsDirty) return;

}

 

internal void DeleteSelf()

{

// if we're not dirty then don't update the database

if (!this.IsDirty) return;

// if we're new then don't update the database

if (this.IsNew) return;

//DeleteRole(_id);

MarkNew();

}

internal static void DeleteUserAccount(int id)

{

}

#endregion

}

}

Marjon1 replied on Wednesday, December 26, 2007

Andrew,

You haven't overriden the DataPortal_Fetch method, you've implemented your own Fetch method. It is unable to find the correct method to call, thus the cause of your error.

Q Johnson replied on Wednesday, December 26, 2007

A Child object cannot Fetch or do any other CRUD operations on its own volition.  The respective Parent must perform these actions.  Usually that will be an Editable Root or Collection object.

 

JoeFallon1 replied on Thursday, December 27, 2007

The other two responders are correct.

You are mixing up child and root concepts.

Since you marked this BO as a child it should be contained in some parent root BO or collection.

A child BO does NOT call DataPortal.Fetch.

e.g. it should look more like this: (note the pased in dr comes from the parent BO.)

Protected Friend Shared Function GetMyChild(ByVal dr As SafeDataReader) AsMyChild
 
Dim child As New MyChild
  child.Fetch(dr)
 
Return child
End Function

Protected Overridable Sub Fetch(ByVal dr As SafeDataReader)
  With dr
    'fill class variables here
  End With

  MarkOld()
  ValidationRules.CheckRules()
End Sub

ataylorm replied on Thursday, December 27, 2007

Thanks for everyones help!  I think I am almost there.  Everything is working except for the save method.  When I make changes to the child, but not changes to the parent the parent.save() doesn't detect that the child isdirty.

 

Marjon1 replied on Thursday, December 27, 2007

You need to override the IsDirty & IsValid on the parent object to detect that the child is valid and/or dirty.

pgroenenstein replied on Wednesday, September 16, 2009

Ok but please show us where does the "dr" comes from? In other words How does the code looks like where "getMyChild" is being called from?

ajj3085 replied on Wednesday, September 16, 2009

It comes from the parent object, which executed the datareader. Note that this thread is rather old, so if you're using the newest Csla you should be using the child dataportal and implementing a Child_Fetch method (which takes a data reader).

pgroenenstein replied on Wednesday, September 16, 2009

Thanks

please give me an overview of what you mean. I 'm confused..some pseudo code perhaps? When I use the dataportal my "object" looks for the DB local instead of on the server. Dataportal obviously not invoked!

ajj3085 replied on Wednesday, September 16, 2009

usually in the parent's DataPortal_Fetch, you'll do something like this:

private void DataPortal_Fetch( obj criteira ) {
// usual load stuff, including getting a dr for the child object)
MyChildObj = ChildObj.Fetch( dr );
}

in your ChildObj class, youll have this:

internal static ChildObj Fetch( DataReader dr ){ return DataPortal.FetchChild( dr ); }

private void Child_Fetch( DataReader dr ) {
// load the child from the dr
}

pgroenenstein replied on Wednesday, September 16, 2009

Got it sorted!

I used the "DataPortal_Create" sub on the object then add it to the collection as a child, marking it as a child as I go. My mistake was to use "Child_Create" first time around.
It is all in the book in Chapter 5 section 'Loading Default Values from a Data Store'.

Copyright (c) Marimer LLC