erotik film
bodyheat full moves www xxx kajal video la figa che sborra ver video de sexo porno
Luxury replica watches
sex
asyabahis
escort antalya

** THIS SITE IS AN ARCHIVE ** - New Content is at:
BlazorHelpWebsite.com

Feb 6

Written by: kchristo
Wednesday, February 6, 2013  RssIcon

In a previous post I suggested a way to override default LightSwitch add/edit behavior. In this post I will suggest an override to default delete behavior.

It has happened many times to delete entries, only to get an error message, when trying to save, informing me about reference constraints being violated and the action cannot be completed. This is not much of problem when you try to delete one record (apart from the fact this message is ugly and not one that I would allow my end users to deal with, for that matter). But when trying to delete many records you have no clue which was the one (or more) record(s) that cannot be deleted. In this case all you can do is delete-save until you find the record that cannot be deleted. And when you find it, you have to refresh your screen or undo the changes of the current record (a future article will suggest a way to do this).

What I needed was a good generic way to be able to set Delete_CanExecute result. This is my suggestion using (what else) extension methods, interfaces (Yann will love me for this Smile) and an attribute.

First the interface to help decide if an instance can be deleted or not:

public interface IDependencyCheck : IEntityObject
{
  bool CanDelete { get; }
}

Quite simple you must admit. Keep in mind interfaces you want to use in your common project have to be accessible both by Server and Client project also. If someone here thinks of EntityName_CanDelete, someone forgets that it is a server side hook.

Now an attribute to help us decide which of the dependencies an entity might have are strong ones, meaning that the referential integrity of the database or your business logic if you don’t use database constraints, would not allow an instance to be deleted.

[AttributeUsage(AttributeTargets.Class)]
public class StrongDependencyAttribute : Attribute
{
  public StrongDependencyAttribute(string dependencies) {
    this.dependencies = dependencies.ToStringArray();
  }

  public string[] Dependencies {
    get { return dependencies; }
  }

  private readonly string[] dependencies;
}

This attribute takes a list of strong reference property names as comma delimited string (or whatever delimiter you like for that matter) using these simple extensions:

public static string[] ToStringArray(this string strings) {
   return strings.ToStringArray(',');
}

public static string[] ToStringArray(this string strings, char delimiter) {
   return (from string item in strings.Split(new char[] { delimiter }, StringSplitOptions.RemoveEmptyEntries)
               select item.Trim()).ToArray();
}

If you want to use another delimiter just replace

this.dependencies = dependencies.ToStringArray();

in the constructor with (for example):

this.dependencies = dependencies.ToStringArray(';');

Or if you want, you can have one instance of the attribute for each property you want to check and avoid delimited strings altogether. Plenty of choices…Smile.

Keep in mind that if you declare no instance of this attribute but you implement IDependencyCheck then ALL dependencies will be considered as strong ones and checked for integrity.

This attribute needs to be accessible by the Common project only.

Now, all that said, there are two extension methods that will help us do the job.

The first one needs to be accessible by the Client project only:

public static bool CanDeleteSelection(this IScreenObject screen, string collectionName) {
   if (!screen.HasSelection(collectionName))
     return false;
   IVisualCollection collection = screen.Details.Properties[collectionName].Value as IVisualCollection;
   if (collection.SelectedItem is IDependencyCheck)
     return (collection.SelectedItem as IDependencyCheck).CanDelete;
   return true;
}

Please note I am using IScreenObject.HasSelection extension that has already been introduced in a previous post. That’s why I am not checking if the cast to IVisualCollection is successful (not null).

The second one has to be accessible by the Common project only:

    public static bool CanDelete(this IEntityObject entity) {
      IEnumerable<IEntityCollectionProperty> collectionProperties = 
        entity.Details.Properties.All()
        .Where(p => p.GetType().GetInterfaces()
          .Where(t => t.Name.Equals("IEntityCollectionProperty"))
          .FirstOrDefault() != null)
        .Cast<IEntityCollectionProperty>();
      if (collectionProperties == null)
        return true;
      List<string> strongDependencies = new List<string>();
      IEnumerable<StrongDependencyAttribute> dependencies = 
        entity.GetType()
        .GetCustomAttributes(typeof(StrongDependencyAttribute), false)
        .Cast<StrongDependencyAttribute>();
      foreach (StrongDependencyAttribute dependency in dependencies)
        strongDependencies.AddRange(dependency.Dependencies);
      bool hasDependencies = strongDependencies.FirstOrDefault() != null;
      bool canDelete = true;
      foreach (IEntityCollectionProperty property in collectionProperties) {
        if (hasDependencies &&strongDependencies.FirstOrDefault(d => d.Equals(property.Name)) == null)
          continue;
        IEnumerable value = entity.GetType()
          .GetProperty(string.Format("{0}Query", property.Name))
          .GetValue(entity, null) as IEnumerable;
        try {
          if (value != null && value.GetEnumerator().MoveNext()) {
            canDelete = false;
            break;
          }
        }
        catch {
          continue;
        }
      }
      return canDelete;
    }

Although it’s obvious at first glance what the code does Hot smile, I will give brief explanation:

If there is not a StrongDependencyAtttibute defined for the entity then all reference properties are checked and if at least one has members then the entity cannot be deleted. If a StrongDependencyAtttibute is defined for the entity then only reference properties included in the attribute are checked. That’s all…

If you manage to read the code (I am not very proud about the absence of comments) you will notice that only one-to-many and many-to-many references are handled. In my world one-to-one references mean inheritance and in this case both objects should be deleted. But what if the base object can be deleted (has no direct references) and the derived object has? Again in my world, if you are trying to delete the base object you are already doing it wrong! Anyway if someone lives in a world other than mine (I am very democratic guy Be right back) and wants to support one-to-one relations all he/she has to do is find where IEntityCollectionProperty definition is and look for the respective property type (I believe it is IEntityReferenceProperty but I am not quite sure).

And for the end an example so that anyone can see what all of the above end up to:

Suppose you have a Customer entity. And this Customer entity has a collection of Orders. The property of the Customer entity that holds these orders is called CustomerOrders. In your Datasource you right-click Customer entity and select View Table Code. A partial class implementation file is created (if it does not already exist). Modify the definition of you class as follows:

[StrongDependency("CustomerOrders")]
public partial class Customer : IDependencyCheck {
...

  #region IDependencyCheck members 
  public bool CanDelete {
    get { return this.CanDelete(); }
  }
  #endregion IDependencyCheck members
}

Remember to reference (using) the namespace where your extension method (CanDelete) is declared.

Please note that IDependencyCheck gives you the potential to write whatever else hardcoded (or not) check you want in your CanDelete property implementation. In the code above I just call the extension method I introduced earlier. But you can do whatever you want. You can even skip the dependencies mechanism suggested altogether. The client side extension will still work.

So in the screen that you have your list of Customers right click the Delete command of the list or grid and in the CustomersDelete_CanExecute just write:

partial void CustomersDelete_CanExecute(ref bool result){
  result = this.CanDeleteSelection("Customers");
}

As partial implementation of Execute write:

partial void CustomersDelete_Execute(){
  this.Customers.DeleteSelected();
}

I know some of you have already noticed the overhead of potentially loading the dependent objects the first time you select an item of your list or grid. I cannot argue with that, except for the fact that my approach is suggested for intranet implementations (I am not sure I would do something like that over the web) and the fact that the time under these circumstances is an acceptable price to pay in order to avoid the annoying referential integrity message. At least in my world Smile

Tags:
Categories:

1 comment(s) so far...


Air Jordan 9
Jordan 11
Golden Goose Sneakers Outlet
Air Jordan 6
Moncler Store
Moncler Jackets
Christian Louboutin
Retro Jordan
Nike Outlet
Jordan Shoes
Jordan 4 Retro
Nike Outlet
Jordan Retro
Jordan Retro 11 Mens
Air Jordan 12
Air Jordan Shoes
Ferragamo Shoes
Red Bottoms Louboutin
NMD
Jordan 14
Snkrs Nike
Nike Kyrie Irving Shoes
Soccer Cleats
Jordan 11's
Nike Air Jordan 5
Jordan Retro 3
Jordan Sneakers
Red Bottom Shoes
Pandora Jewelry
Fjallraven Kanken
Yeezy Shoes
James Harden shoes
Golden Goose Sneakers Men
Yeezys
GGDB
Air Jordan Sneakers
Golden Gooses Sneakers
Pandora Charms
Jordan 6 Retro
Jordan 11 For Sale
Air Max 2018
Golden Goose Sale
Pandora Charms
New Jordans
Jordan 11's
Jordans 11
New Jordans 2021
Jordan 1
Jordan Shoes
Cheap Jordan Shoes For Women
Nike Air Force
Nike Outlet Store Online Shopping
Nike Air Max 270
Golden Goose Mid Star
Louboutin Shoes
Jordan 11
Moncler Outlet
Air Max 90
Pandora
Balenciaga Sneakers
GGDB
Jordan 12 Retro
Balenciaga Triple S
Moncler Outlet Store
Yeezys
Jordan Retro 11
Valentino Sandals
Moncler Jackets For Women
Yeezy
Jordan 6
Jordans Sneakers
GGDB Sneaker
Pandora Ring
Jordan Sneakers
Huaraches Nike
Air Jordan Retro 10
Jordans 4
Fitflops Sale Clearance
Air Max 98
Nike Factory Outlet
Pandora Official Site
Fitflop Shoes
Red Jordan 11
Air Jordan Retro 12
Jordan 3
Pandora Jewelry
Jordan Retro 4
Nike Official Website
Golden Goose Sneakers
Pandora Ring
Moncler
Jordan 4
Jordan Shoes For Men
Jordan Retro 5
Nike Air Max 95
Air Jordan 11
Red Bottoms
Nike Shoes Women
Jordan Retro 8
Air Jordan 11
James Harden Shoes
Moncler Vest
Adidas Yeezy
Nike Air Max
Pandora
Hermes Birkin
Golden Goose Sneakers Sale
Mens Nike Shoes
Nike Outlet Store Online
Win Like 96
Yeezy
Ferragamo Outlet
Cheap Nike Shoes
Adidas NMD
New Nike Shoes
Air Force One Shoes
Nike Outlet
Pandora Charms Outlet
Cheap Jordan Shoes
Air Jordans
Pandora Jewelry Official Site
Nike Shoes On Sale
Golden Goose Shoes
Pandora Jewelry
Air Jordan
Retro Jordans
Golden Goose Factory Outlet
Nike Shoes For Women
Jordan 5
Moncler Jackets Outlet
Jordans Retro
Pandora Bracelets
Jordan Retro 12
Moncler Jackets
Jordan 13
ECCO

By Barbara on   Wednesday, July 14, 2021

Your name:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation