integer fields specified in the exclude list not excluded

Posts   
 
    
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 22-Apr-2008 09:05:12   

build: 21st april scenario: adapter db: northwind

Hi,

It looks like int fields are not excluded when added to the ExcludeFields.

var q1 = (from f in meta.Territory
               select f).ExcludeFields(f => f.RegionId);
: Initial expression to process:
value(SD.LLBLGen.Pro.LinqSupportClasses.DataSource2`1[Orangehill.Linq2LLBLGen.EntityClasses.TerritoryEntity]).Select(f => f).ExcludeFields(value(System.Linq.Expressions.Expression`1[System.Func`2[Orangehill.Linq2LLBLGen.EntityClasses.TerritoryEntity,System.Object]][]))
Executed Sql Query: 
    Query: SELECT DISTINCT [LPLA_1].[TerritoryID] AS [TerritoryId], [LPLA_1].[TerritoryDescription], [LPLA_1].[RegionID] AS [RegionId] FROM [Northwind].[dbo].[Territories] [LPLA_1] 

Regards, Arjan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39863
Joined: 17-Aug-2003
# Posted on: 22-Apr-2008 09:53:23   

THis is by design: FK fields, PK fields aren't excludable. This is because they can be used for further processing, like the FK field values which are used to produce relationinfo objects for filters to fetch related data.

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 03-Oct-2008 13:21:29   

I just ran across a situation where I needed to force an FK field to be excluded from the search.

The class below worked for my situation - just use it in place of ExcludeFieldsList. All it is does it put a wrapper around an FK field to always return false when IsForeignKey queried.

    public class ExcludeFieldsListAce: ExcludeFieldsList
    {
        public ExcludeFieldsListAce(params IEntityFieldCore[] fields): this(fields, true) {}
        public ExcludeFieldsListAce(IEnumerable<IEntityFieldCore> fields): this(fields, true) {}

        ExcludeFieldsListAce(IEnumerable<IEntityFieldCore> fields, bool ignore)
        {
            foreach(IEntityFieldCore field in fields)
            {
                if (field.IsForeignKey)
                {
                    Add(new ForceExcludedField(field));
                    return;
                }

                Add(field);
            }
        }

        class ForceExcludedField: IEntityFieldCore
        {
            readonly IEntityFieldCore realField;

            public ForceExcludedField(IEntityFieldCore realField)
            {
                this.realField = realField;
            }

            /// <summary>
            /// Always returns false so that LLCoolJ doesn't know that the field
            /// is a FK and so will really exclude it from the query.
            /// </summary>
            public bool IsForeignKey
            {
                get { return false; }
            }

            #region Delegated Implementation of IEntityFieldCore
            public void BeginEdit() { realField.BeginEdit(); }
            public void EndEdit() { realField.EndEdit(); }
            public void CancelEdit() { realField.CancelEdit(); }
            public string Name { get { return realField.Name; } }
            public Type DataType { get { return realField.DataType; } }
            public bool IsPrimaryKey { get { return realField.IsPrimaryKey; } }
            public bool IsNullable { get { return realField.IsNullable; } }
            public int FieldIndex { get { return realField.FieldIndex; } }
            public string ContainingObjectName { get { return realField.ContainingObjectName; } }
            public bool IsReadOnly { get { return realField.IsReadOnly; } }
            public int MaxLength { get { return realField.MaxLength; } }
            public byte Scale { get { return realField.Scale; } }
            public byte Precision { get { return realField.Precision; } }
            public string ActualContainingObjectName { get { return realField.ActualContainingObjectName; } }
            public bool IsInMultiTargetEntity { get { return realField.IsInMultiTargetEntity; } }
            public void ForcedCurrentValueWrite(object value) { realField.ForcedCurrentValueWrite(value); }
            public void ForcedCurrentValueWrite(object value, object dbValue) { realField.ForcedCurrentValueWrite(value, dbValue); }
            public bool GetDiscriminatorColumnFlag() { return realField.GetDiscriminatorColumnFlag(); }
            public IEntityFieldCore Clone() { return realField.Clone(); }
            public string Alias { get { return realField.Alias; } set { realField.Alias = value; } }
            public object CurrentValue { get { return realField.CurrentValue; } set { realField.CurrentValue = value; } }
            public object DbValue { get { return realField.DbValue; } }
            public bool IsChanged { get { return realField.IsChanged; } set { realField.IsChanged = value; } }
            public bool IsNull { get { return realField.IsNull; } set { realField.IsNull = value; } }
            public string ObjectAlias { get { return realField.ObjectAlias; } set { realField.ObjectAlias = value; } }
            public AggregateFunction AggregateFunctionToApply { get { return realField.AggregateFunctionToApply; } set { realField.AggregateFunctionToApply = value; } }
            public IExpression ExpressionToApply { get { return realField.ExpressionToApply; } set { realField.ExpressionToApply = value; } }
            public IEntityFieldCore LinkedSuperTypeField { get { return realField.LinkedSuperTypeField; } set { realField.LinkedSuperTypeField = value; } }
            public bool ActAsDerivedTableField { get { return realField.ActAsDerivedTableField; } }
            #endregion Delegated Implementation of IEntityFieldCore
        }
    }

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39863
Joined: 17-Aug-2003
# Posted on: 03-Oct-2008 13:54:50   

I know you aren't fond of a few extra bytes here and there wink but why would the exclusion of an FK be so important in this case?

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 06-Oct-2008 07:17:38   

Otis wrote:

I know you aren't fond of a few extra bytes here and there wink but why would the exclusion of an FK be so important in this case?

Well I'd left this one at the river, but since you ask... simple_smile

1) I like being in control. If I don't want a field to be retrieved then I don't want it retrieved and if there is a problem later on because associated entities can't be matched then that is my look out and I'm happy with that.

2) In this particular case, I didn't have a choice. Our dev database got a new, nullable FK field in a particular table. However I needed to access some real data from the Live DB. Since LLCoolJ insists on ignoring me and retrieving the field anyway, the routine crashed because the generated query wants to retrieve the field that ain't there! I looked at the LLCoolJ code and found you had it pretty well locked up good! The above routine worked first time for me.

Cheers Simon

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39863
Joined: 17-Aug-2003
# Posted on: 06-Oct-2008 11:00:15   

simmotech wrote:

Otis wrote:

I know you aren't fond of a few extra bytes here and there wink but why would the exclusion of an FK be so important in this case?

Well I'd left this one at the river, but since you ask... simple_smile

1) I like being in control. If I don't want a field to be retrieved then I don't want it retrieved and if there is a problem later on because associated entities can't be matched then that is my look out and I'm happy with that.

I understand. simple_smile The point is though that to track down the REAL issue is a bit difficult in some situations, like with prefetch paths (which use the same code)

2) In this particular case, I didn't have a choice. Our dev database got a new, nullable FK field in a particular table. However I needed to access some real data from the Live DB. Since LLCoolJ insists on ignoring me and retrieving the field anyway, the routine crashed because the generated query wants to retrieve the field that ain't there! I looked at the LLCoolJ code and found you had it pretty well locked up good! The above routine worked first time for me. Cheers Simon

heh simple_smile

Ok, I see why this would be necessary in this case indeed. Luckily the workaround was easy enough wink

Frans Bouma | Lead developer LLBLGen Pro