清除 Lightswitch 内部数据库
Clear Lightswitch intrinsic database
Lightswitch(桌面应用程序,浏览器外)散布在各处的文档非常有限。我正在寻找一种方法来清除内部数据库中的所有数据,以便在进行重大更改后添加新数据。
这是我目前唯一可行的解决方案:
- 为我拥有的每个
VisualCollection
写一个 DeleteAll()
方法。
- 例如,向屏幕添加事件或按钮。
- 调用所有
DeleteAll()
方法(在触发事件或单击按钮时)。
- 保存。
这显然根本没有效率而且非常不干。我想要的是某种 ClearDatabase()
仅用于开发和调试的方法。
所以这是我的问题的两个重要部分:
- 我能否(如果可以,我将如何)在我的
ApplicationData
中获取所有 EntitySets
而无需硬编码?
- 是否可以从我的应用程序的客户端调用这样的方法?我想也许在自动生成的
Application.Application_Initialize()
.
由于在 post 互联网上似乎完全没有这个问题的答案,我通过挖掘 Lightswitch 的代码想出了新代码。
这是我编写的一个有效的、经过测试的解决方案。只需按照这些非常简单的步骤操作即可。
在解决方案资源管理器中,在 yourAppName.Server 下,创建一个名为 UserCode
,如果它还不存在。
在该文件夹中,添加一个名为 DataUtilities
的新 class。
删除新 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();
}
}
}
}
}
再次执行步骤 1,但这次在 yourAppName.DesktopClient 下。您现在应该有 2 个名为 UserCode
的文件夹,一个在应用程序的两侧。
右键单击最后一个文件夹(UserCode
in yourAppName.DesktopClient) ,转到 添加 然后 现有元素....
导航至...\yourAppName\yourAppName.Server\UserCode.
Select DataUtilities.cs
,然后点击 Add[=111= 旁边的小向下箭头] 按钮。选择 添加为 link。现在 class 可以在服务器端和客户端使用。
现在让我们使用新的扩展方法!
返回解决方案资源管理器,右键单击 yourAppName.DesktopClient,然后 select 显示应用程序代码(应该是下拉菜单中的第一个选项)。
用这个替换生成的代码(或者,如果你已经在 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.
}
}
瞧!下次启动应用程序时,存储在内部数据库中的所有数据都应该消失。
有关代码的更多信息:
工作原理
我不会在这里解释整个过程,但基本上:
DeleteAllSets(...)
将获取数据源的所有 EntitySets
并对每个数据源调用 DeleteSet(...)
。
DeleteSet(...)
将在 EntitySet
. 中的每个实体上调用已经存在的 Delete()
方法
如何排除数据被删除
您还可以将 Type 参数传递给 DeleteAllSets(...)
方法以从删除过程中排除这些参数:
假设我有 2 个 table 分别存储员工数据和产品数据。将那些 table 称为 Employee
和 Product
。例如,如果我在 Product
table 中添加了测试数据,并且想在不删除所有员工的情况下删除它,我会使用这样的扩展方法:
Current.CreateDataWorkspace().DeleteAllSets(typeof(Employee));
这只会删除 Product
table 中的所有实体。
我希望这可以帮助任何坚持使用 Lightswitch 的不那么容易的调试和测试的人!整个过程大概是翻译table到网页版,我会留给其他人。
Lightswitch(桌面应用程序,浏览器外)散布在各处的文档非常有限。我正在寻找一种方法来清除内部数据库中的所有数据,以便在进行重大更改后添加新数据。
这是我目前唯一可行的解决方案:
- 为我拥有的每个
VisualCollection
写一个DeleteAll()
方法。 - 例如,向屏幕添加事件或按钮。
- 调用所有
DeleteAll()
方法(在触发事件或单击按钮时)。 - 保存。
这显然根本没有效率而且非常不干。我想要的是某种 ClearDatabase()
仅用于开发和调试的方法。
所以这是我的问题的两个重要部分:
- 我能否(如果可以,我将如何)在我的
ApplicationData
中获取所有EntitySets
而无需硬编码? - 是否可以从我的应用程序的客户端调用这样的方法?我想也许在自动生成的
Application.Application_Initialize()
.
由于在 post 互联网上似乎完全没有这个问题的答案,我通过挖掘 Lightswitch 的代码想出了新代码。
这是我编写的一个有效的、经过测试的解决方案。只需按照这些非常简单的步骤操作即可。
在解决方案资源管理器中,在 yourAppName.Server 下,创建一个名为
UserCode
,如果它还不存在。在该文件夹中,添加一个名为
DataUtilities
的新 class。删除新 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(); } } } } }
再次执行步骤 1,但这次在 yourAppName.DesktopClient 下。您现在应该有 2 个名为
UserCode
的文件夹,一个在应用程序的两侧。右键单击最后一个文件夹(
UserCode
in yourAppName.DesktopClient) ,转到 添加 然后 现有元素....导航至...\yourAppName\yourAppName.Server\UserCode.
Select
DataUtilities.cs
,然后点击 Add[=111= 旁边的小向下箭头] 按钮。选择 添加为 link。现在 class 可以在服务器端和客户端使用。现在让我们使用新的扩展方法!
返回解决方案资源管理器,右键单击 yourAppName.DesktopClient,然后 select 显示应用程序代码(应该是下拉菜单中的第一个选项)。
用这个替换生成的代码(或者,如果你已经在 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. } }
瞧!下次启动应用程序时,存储在内部数据库中的所有数据都应该消失。
有关代码的更多信息:
工作原理
我不会在这里解释整个过程,但基本上:
DeleteAllSets(...)
将获取数据源的所有EntitySets
并对每个数据源调用DeleteSet(...)
。DeleteSet(...)
将在EntitySet
. 中的每个实体上调用已经存在的
Delete()
方法
如何排除数据被删除
您还可以将 Type 参数传递给 DeleteAllSets(...)
方法以从删除过程中排除这些参数:
假设我有 2 个 table 分别存储员工数据和产品数据。将那些 table 称为 Employee
和 Product
。例如,如果我在 Product
table 中添加了测试数据,并且想在不删除所有员工的情况下删除它,我会使用这样的扩展方法:
Current.CreateDataWorkspace().DeleteAllSets(typeof(Employee));
这只会删除 Product
table 中的所有实体。
我希望这可以帮助任何坚持使用 Lightswitch 的不那么容易的调试和测试的人!整个过程大概是翻译table到网页版,我会留给其他人。