我是 WCF RIA 服务的新手,现在使用 LightSwitch 已经有 4 个月左右的时间了。我创建了一个通用屏幕,用于在整个 LightSwitch 应用程序中编辑查找表,主要是为了学习如何创建一个通用屏幕,该屏幕可以动态地与不同的实体集一起使用。
画面很简单:
使用类似于以下的参数打开:
Application.ShowLookupTypesList("StatusTypes", "StatusTypeId");
它对应于数据库中查找表的实体集。
这是我的 WCF RIA 服务代码:
using System.Data.Objects.DataClasses;
using System.Diagnostics;
using System.Reflection;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Server;
namespace WCF_RIA_Project
{
public class LookupType
{
[Key]
public int TypeId { get; set; }
public string Name { get; set; }
}
public static class EntityInfo
{
public static Type Type;
public static PropertyInfo Key;
public static PropertyInfo Set;
}
public class WCF_RIA_Service : LinqToEntitiesDomainService<WCSEntities>
{
public IQueryable<LookupType> GetLookupTypesByEntitySet(string EntitySetName, string KeyName)
{
EntityInfo.Set = ObjectContext.GetType().GetProperty(EntitySetName);
EntityInfo.Type = EntityInfo.Set.PropertyType.GetGenericArguments().First();
EntityInfo.Key = EntityInfo.Type.GetProperty(KeyName);
return GetTypes();
}
[Query(IsDefault = true)]
public IQueryable<LookupType> GetTypes()
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
var types = from e in set
select new LookupType
{
TypeId = (int)EntityInfo.Key.GetValue(e, null),
Name = (string)EntityInfo.Type.GetProperty("Name").GetValue(e, null)
};
return types.AsQueryable();
}
public void InsertLookupType(LookupType lookupType)
{
dynamic e = Activator.CreateInstance(EntityInfo.Type);
EntityInfo.Key.SetValue(e, lookupType.TypeId, null);
e.Name = lookupType.Name;
dynamic set = EntityInfo.Set.GetValue(ObjectContext, null);
set.AddObject(e);
}
public void UpdateLookupType(LookupType currentLookupType)
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
dynamic modified = set.FirstOrDefault(t => (int)EntityInfo.Key.GetValue(t, null) == currentLookupType.TypeId);
modified.Name = currentLookupType.Name;
}
public void DeleteLookupType(LookupType lookupType)
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
var e = set.FirstOrDefault(t => (int)EntityInfo.Key.GetValue(t, null) == lookupType.TypeId);
Debug.Assert(e.EntityState != EntityState.Detached, "Entity was in a detached state.");
ObjectContext.ObjectStateManager.ChangeObjectState(e, EntityState.Deleted);
}
}
}
当我从运行屏幕将项目添加到列表中,保存它,然后编辑它并重新保存时,我收到数据冲突“另一个用户已删除此记录”。
我可以通过在保存后重新加载查询来解决这个问题,但这很尴尬。
如果我删除、保存、读取并保存一个具有相同名称的项目,我将无法保存数据,“上下文已经在跟踪具有相同资源 Uri 的不同实体。”
这两个问题只影响我使用 WCF RIA 服务的通用屏幕。当我为特定数据库实体构建 ListDetail 屏幕时,没有问题。看来我缺少一些逻辑,有什么想法吗?