Clear Lightswitch内在数据库

时间:2016-12-13 17:43:39

标签: c# database silverlight visual-studio-lightswitch

Lightswitch(桌面应用程序,浏览器外)在这里和那里分散的文档非常有限。我正在寻找一种方法来清除内部数据库中的所有数据,以便在进行重大更改后添加新数据。

这是我现在唯一可行的解​​决方案:

  1. 为我拥有的每个DeleteAll()写一个VisualCollection方法。
  2. 例如,在屏幕上添加一个事件或按钮。
  3. 调用所有DeleteAll()方法(在事件触发或按钮点击时)。
  4. 保存。
  5. 这显然效率不高,而且非DRY。我想要的是某种ClearDatabase()方法,我只用于开发和调试。

    以下是我提问的两个重要部分:

    • 我可以(如果是,我将如何)在没有硬编码的情况下获取EntitySets中的所有ApplicationData
    • 是否可以从我的应用程序的客户端调用此类方法?我想的可能是自动生成的Application.Application_Initialize()

1 个答案:

答案 0 :(得分:0)

由于在这篇文章发表时,似乎在互联网上似乎没有回答这个问题,我通过挖掘Lightswitch的代码想出了新的代码。

这是我写的一个经过测试的有效解决方案。只需遵循这些非常简单的步骤。

  1. 在解决方案资源管理器中,在 yourAppName.Server 下,创建一个名为UserCode的新文件夹(如果该文件夹尚不存在)。
  2. 在该文件夹中,添加名为DataUtilities
  3. 的新类
  4. 删除该新类中的所有代码,并粘贴以下代码:

    using Microsoft.LightSwitch;
    using Microsoft.LightSwitch.Details;
    using Microsoft.LightSwitch.Framework;
    using Microsoft.LightSwitch.Threading;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Linq;
    using System.Reflection;
    
    namespace LightSwitchApplication.UserCode
    {
        public static class DataUtilities
        {
            public static void DeleteAllSets(this DataWorkspace workspace, params Type[] excludedTypes)
            {
                List<Type> listExcludedTypes = excludedTypes.ToList();
                ApplicationData appData = workspace.ApplicationData;
                IEnumerable<IDataServiceProperty> properties = appData.Details.Properties.All();
    
                foreach (IDataServiceProperty prop in properties)
                {
                    dynamic entitySet = prop.Value;
                    Type entityType = entitySet.GetType().GetGenericArguments()[0];
    
                    if (!listExcludedTypes.Contains(entityType))
                    {
                        typeof(DataUtilities).GetMethod("DeleteSet", BindingFlags.Static | BindingFlags.Public)
                                            .MakeGenericMethod(entityType)
                                            .Invoke(null, new object[] { entitySet });
                    }
                }
    
                appData.SaveChanges();
            }
    
            public static void DeleteSet<T>(this EntitySet<T> entities) where T: 
                IDispatcherObject, IObjectWithDetails, IStructuralObject, INotifyPropertyChanged, IBusinessObject, IEntityObject
            {
                List<T> entityList = entities.Select(e => e).Execute().ToList();
                int entityCount = entityList.Count();
    
                for (int i = 0; i < entityCount; i++)
                {
                    T entity = entityList.ElementAt(i);
                    if (entity != null) 
                    { 
                        // Uncomment the line below to see all entities being deleted.
                        // Debug.WriteLine("DELETING " + typeof(T).Name + ": " + entity); 
                        entity.Delete(); 
                    }
                }
            }
        }
    }
    
  5. 再次执行第1步,但这次是在 yourAppName.DesktopClient 下。您现在应该有2个名为UserCode的文件夹,一个位于应用程序的两侧。

  6. 右键点击最后一个文件夹( yourAppName.DesktopClient 中的UserCode),转到 添加 < / strong>然后 现有元素......
  7. 导航至 ... \ yourAppName \ yourAppName.Server \ UserCode
  8. 选择DataUtilities.cs,然后点击 添加 按钮旁边的小向下箭头。选择 添加为链接 。现在,该类可以在服务器端和客户端使用。

    现在让我们使用新的扩展方法!

  9. 返回解决方案资源管理器,右键单击 yourAppName.DesktopClient ,然后选择 显示应用程序代码 < / strong>(应该是下拉菜单中的第一个选项)。

  10. 用此替换生成的代码(或者,如果您已在该类中添加了一些自定义代码,请添加我在Application_Initialize()中显示的单行):

    using LightSwitchApplication.UserCode;
    
    namespace LightSwitchApplication
    {
        public partial class Application
        {
            partial void Application_Initialize()
            {
                Current.CreateDataWorkspace().DeleteAllSets();
            }
    
            //Some other methods here if you already modified this class.
        }
    }
    
  11. 瞧!下次启动应用程序时,存储在内部数据库中的所有数据都应该消失。
  12. 有关代码的更多信息:

    工作原理

    我不会在这里解释整个过程,但基本上是:

    • DeleteAllSets(...)将获取数据源的所有EntitySets,并在每个数据源上调用DeleteSet(...)
    • DeleteSet(...)会调用Delete()中每个实体的现有EntitySet方法。

    如何从删除中排除数据

    您还可以将Type参数传递给DeleteAllSets(...)方法,以从删除过程中排除这些参数:

    假设我有2个表分别存储员工数据和产品数据。让这些表格称为EmployeeProduct。例如,如果我在Product表中添加了测试数据,并希望摆脱它,而不删除所有员工,我会使用这样的扩展方法:

    Current.CreateDataWorkspace().DeleteAllSets(typeof(Employee));
    

    这将仅删除Product表中的所有实体。

    我希望这可以帮助任何坚持使用Lightswitch不那么容易的调试和测试的人!整个过程可能会转换为Web版本,但我会将其留给其他人。