Contructor with fields

Posts   
 
    
netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 08-Mar-2004 17:18:29   

I'm looking for a way of dynamically controlling what fields are returned to the client. I figured i would be able to do this using the contructor of an entity that takes an IEntitiyFields2 as a parameter but using this and supplying a list of fields to use seems to have dire consequences, due to the fact that the fields don't match up with the fieldindex of the entity.

Is there anyway i can do this?

Here's what i tried:

        public static BusinessObjects.boContactsEntity NewContact()
        {
            int count = 4;
            ArrayList arrFields = new ArrayList();
            arrFields.Add("CONTACT_NO");
            arrFields.Add("COMPANY_NO");
            arrFields.Add("CON_NAME1");
            arrFields.Add("CON_NAME2");
                        
            ResultsetFields fields = new ResultsetFields(count);    
            count = 0;
            for(int i=0;i<(int)CONTACTSFieldIndex.AmountOfFields;i++)
            {
                if (arrFields.IndexOf(((CONTACTSFieldIndex)i).ToString()) > -1)
                {
                    fields.DefineField((CONTACTSFieldIndex)i, count, arrFields[count].ToString());
                    count++;
                }   
            }

            BusinessObjects.boContactsEntity con = new BusinessObjects.boContactsEntity(fields);
            return con;
        }

this results in an exception:

The field index passed is not a valid index in the fields collection of this entity. Parameter name: fieldIndex Actual value was 6.

when it comes to setting the value for the field because the value in the field index for the field is greater than the number of fields in the fields collection.

Please tell me there's a way i can achieve this? simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 09-Mar-2004 09:47:55   

Checking where that exception is thrown, it is done in the routine which retrieves a field value in an entity class: an index is passed in which is larger than the amount of fields in the fieldslist.

What you should do is first create an EntityFields2 instance which is big enough to hold all fields, then create the EntityField2 instances, using the factories. You can then 'plug in' the fields object into an entity:

myCustomer.Fields = newFields;

and myCustomer will have a complete new fields set. simple_smile

BUt I'm perhaps completely off base here, could you elaborate a bit more about what you're trying to achieve? simple_smile

Frans Bouma | Lead developer LLBLGen Pro
netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 09-Mar-2004 11:50:39   

Basically, i've got an entity class with lots of fields. I'd like to be able to instantiate an instance of that entity but with a cut down set of fields, i don't want to pass all the fields to the client.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 09-Mar-2004 13:16:39   

netclectic wrote:

Basically, i've got an entity class with lots of fields. I'd like to be able to instantiate an instance of that entity but with a cut down set of fields, i don't want to pass all the fields to the client.

I then think you'd better set the CurrentValue of those fields to the default value of the type they have on the EntityFields2 indexes of the fields you don't want to send to the client. You can do that in an EntityFactory2 subclass.

All properties, for example CustomerID index into the fields, and use the entity field indexes to do that. If you remove a lot of fields, these indexes will not be correct and you'll get the exception.

To set a field to the default value, use the TypeDefaultValue class (in both adapter vs.net projects this class is generated and available) and its static method GetDefaultValue. Pass the EntityField2's property DataType (thus myEntity.Fields[index].DataType).

Frans Bouma | Lead developer LLBLGen Pro
netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 09-Mar-2004 19:15:43   

I'm not sure i follow.

Maybe i'm coming at this from the wrong angle... what i need is effectively a view, but the fields in the view aren't know at design time, it has to be configured dynamically at runtime based on input from the client and existing configuration data stored in the database (e.g. another entity).

Say for example i have a Customer entity (id, name, phone, fax, email), and three possible clients accessing customer data (asp.net web interface, .net remoting interface & asp.net webservices interface). Now depending on security settings, each client might be allowed to view different amounts of customer data, e.g. whoever is logged in is not allowed to view phone numbers.

I can quite easily control what can be viewed from the web interface because i'm writing it, but the remoting and webservices interfaces may be provided by a third party which i can't rely on to only show specific data so i have to not provide them with the data in the first place.

So what i need to be able to do is create an instance of an entity (or whatever) that contains just a subset of data that is determined at runtime.

Can this be done? Am i missing something?

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 10-Mar-2004 01:42:00   

I would love this functionality as well. However, it seems that it would be difficult to provide/limit access to related objects; it would have to be all or nothing it seems for related objects and I'm not sure that would meet your need. I've asked in the past for some sort of mechanism for programmatically accessing related objects fields the way you can local object fields via .Fields(CustomerFieldIndex.Name), but none of this would actually prohibit the transfer of data from the db; it would just allow you to build static objects with certain fields.

Jeff...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 10-Mar-2004 09:56:43   

As entity classes are static (not dynamic) it's impossible to create an entity with just the subset of the fields: the class will always have the same properties, no matter what kind of fields you put in the Fields object.

So as I said: if you reset some fields to their default value, you will not send the actual data over when you send the entity over, just default values. You can't set the field to null, as the xml routines expect a field instance there. (so do the properties). Do this in a subclass of the entity factory and override the Create(IEntityFields2 fields) method.

Another possibility is to setup a datatable using the same logic a typed view is setup. You then construct the resultsetfields object manually and fill the datatable using the FetchTypedView() method of the adapter, passing in a normal datatable object.

This is of course read-only data, however it gets your data accross.

Frans Bouma | Lead developer LLBLGen Pro