Entity type - Table or View

Posts   
 
    
jovball
User
Posts: 441
Joined: 23-Jan-2005
# Posted on: 04-Jul-2011 23:59:06   

For code generation purposes, I would like to know when the data source for an entity is a view rather than a table.

I don't see any way to get this now so I am adding a custom property (EntitySourceType) to the views.

In the case that I am not the only one looking for this, I'd like to see another attribute added for this and exposed as a property of EntityDefinition.



<EntityMapping EntityName=":Customers" TargetName="Northwind:dbo:Customers" SourceType="Table">


<EntityMapping EntityName=":OrderHeaderView" TargetName="Northwind:dbo:vw_OrderHeader" SourceType="View">


daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 05-Jul-2011 04:55:35   

Why is the reason you need this? Why is the scenario you would face in which you must know something like that?

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 05-Jul-2011 09:20:24   

and where is the property to be added (not that I think it's necessary, you can determine the target type by looking at the mapped target in the entity mapping)? If you want this to be added to the llblgenproj file, you won't get it, as that file is designed to only contain information which can't be determined at runtime/load time. As the info you're after is determinable at load time, it won't be added.

Frans Bouma | Lead developer LLBLGen Pro
jovball
User
Posts: 441
Joined: 23-Jan-2005
# Posted on: 09-Jul-2011 06:34:44   

This is not a big deal to me because I can solve it with a custom property. However, to answer the "why" question...

I have a business "need" to update only the data that is changed. LLBLGen entities do this very well when they are mapped to tables. However, if they are mapped to a view that is not updateable, the normal solution is to use a trigger.

As far as I know, there is no way to write a trigger that will only touch the changed fields.

My solution for this at this point is to generate custom BL code for the views that populates the entities it represents with the changed data.

As a very simplified example, imagine the following (non-updateable) view.


CREATE VIEW dbo.vw_Products
AS
SELECT
    -- Products
    p.ProductID 
    , p.ProductName 
    , p.QuantityPerUnit 
    , p.UnitPrice 
    , p.UnitsInStock 
    , p.UnitsOnOrder 
    , p.ReorderLevel 
    , p.Discontinued 
    , p.LastUpdate 
    -- Categories
    , c.CategoryID
    , c.CategoryName
    , c.Description
    -- Suppliers
    , s.SupplierID
    , s.CompanyName As Supplier
FROM 
    dbo.Products p
    INNER JOIN dbo.Categories c
    ON p.CategoryID = c.CategoryID 
    INNER JOIN dbo.Suppliers s
    ON p.SupplierID = s.SupplierID 

My code to save only the changed fields looks like this. I only want to generate the first method below for an entity that is based upon a view.


public void SaveProductViewEntity(ProductViewEntity productView)
        {
            ProductEntity product = new ProductEntity();
            PopulateEntityChangedFields(productView, product);

            using (DataAccessAdapter dataAdapter = new DataAccessAdapter())
            {
                dataAdapter.SaveEntity(product);
            }
        }


///<summary>
        /// Populates an entity with the changed fields of another entity, typically a view that is not updateable.
        /// Field values in the toFill entity will only be be set if they meet three conditions.
        /// 1) The field is not read-only in the toFill entity.
        /// 2) There is a matching field name in both entities.
        /// 3) The inputEntity field has been changed.      
        /// </summary>
        /// <param name="inputEntity">The input entity.</param>
        /// <param name="toFill">An entity to populate with any changed data.</param>
        public void PopulateEntityChangedFields(IEntity2 inputEntity, IEntity2 toFill)
        {
            foreach (IEntityField2 field in toFill.Fields)
            {
                if (!field.IsReadOnly && inputEntity.Fields.Contains(field))
                {
                    if ( inputEntity.Fields[field.Name].IsChanged)
                    {
                        field.CurrentValue = inputEntity.Fields[field.Name].CurrentValue;
                    }
                }
            }
        }


One other thought about this. Is there a way I could do this using groups instead of custom properties?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 09-Jul-2011 08:24:49   

jovball wrote:

One other thought about this. Is there a way I could do this using groups instead of custom properties?

No, I don't see how Groups would be useful for you in this case. Groups are used either for visual separation only or to generate a vsnet project per-group, but you can't use them to discriminate entities in your own code. I think your 'Custom Properties' approach is the way to go here.

David Elizondo | LLBLGen Support Team