清除 Lightswitch 内部数据库

Clear Lightswitch intrinsic database

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

这是我目前唯一可行的解​​决方案:

  1. 为我拥有的每个 VisualCollection 写一个 DeleteAll() 方法。
  2. 例如,向屏幕添加事件或按钮。
  3. 调用所有 DeleteAll() 方法(在触发事件或单击按钮时)。
  4. 保存。

这显然根本没有效率而且非常不干。我想要的是某种 ClearDatabase() 仅用于开发和调试的方法。

所以这是我的问题的两个重要部分:

由于在 post 互联网上似乎完全没有这个问题的答案,我通过挖掘 Lightswitch 的代码想出了新代码。

这是我编写的一个有效的、经过测试的解决方案。只需按照这些非常简单的步骤操作即可。

  1. 在解决方案资源管理器中,在 yourAppName.Server 下,创建一个名为 UserCode,如果它还不存在。

  2. 在该文件夹中,添加一个名为 DataUtilities 的新 class。

  3. 删除新 class 中的所有代码,然后粘贴此代码:

    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(); 
                    }
                }
            }
        }
    }
    
  4. 再次执行步骤 1,但这次在 yourAppName.DesktopClient 下。您现在应该有 2 个名为 UserCode 的文件夹,一个在应用程序的两侧。

  5. 右键单击最后一个文件夹(UserCode in yourAppName.DesktopClient) ,转到 添加 然后 现有元素....

  6. 导航至...\yourAppName\yourAppName.Server\UserCode.

  7. Select DataUtilities.cs,然后点击 Add[=111= 旁边的小向下箭头] 按钮。选择 添加为 link。现在 class 可以在服务器端和客户端使用。

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

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

  9. 用这个替换生成的代码(或者,如果你已经在 class 中有一些自定义代码,添加我在 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.
        }
    }
    
  10. 瞧!下次启动应用程序时,存储在内部数据库中的所有数据都应该消失。


有关代码的更多信息:

工作原理

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

  • DeleteAllSets(...) 将获取数据源的所有 EntitySets 并对每个数据源调用 DeleteSet(...)
  • DeleteSet(...) 将在 EntitySet.
  • 中的每个实体上调用已经存在的 Delete() 方法

如何排除数据被删除

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

假设我有 2 个 table 分别存储员工数据和产品数据。将那些 table 称为 EmployeeProduct。例如,如果我在 Product table 中添加了测试数据,并且想在不删除所有员工的情况下删除它,我会使用这样的扩展方法:

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

这只会删除 Product table 中的所有实体。


我希望这可以帮助任何坚持使用 Lightswitch 的不那么容易的调试和测试的人!整个过程大概是翻译table到网页版,我会留给其他人。