1

我是 WCF RIA 服务的新手,现在使用 LightSwitch 已经有 4 个月左右的时间了。我创建了一个通用屏幕,用于在整个 LightSwitch 应用程序中编辑查找表,主要是为了学习如何创建一个通用屏幕,该屏幕可以动态地与不同的实体集一起使用。

画面很简单:

LightSwitch 中的通用 LookupTypesList

使用类似于以下的参数打开: 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 屏幕时,没有问题。看来我缺少一些逻辑,有什么想法吗?

4

2 回答 2

1

我了解到这是使用 LightSwitch 的错误方法。

这个通用屏幕无法完全模拟一些幕后的东西,如果不做大量工作可能无法实现。我收到的错误只是一个例子。LightSwitch 的内置冲突解决也将失败

LS 的 RAD 设计意味着只创建一堆相似的屏幕是可行的方法,并有一些共享的方法。如果实际布局需要同时在许多相同的屏幕上更改,.lsml如果您小心并先进行备份,您始终可以找到并替换文件。请注意,不支持直接修改这些文件。

于 2012-12-12T20:58:20.277 回答
0

我最近收到了这个错误。在我的例子中,我在我的 WCF RIA 服务中创建了一个唯一 ID,但是在我的代码后面的屏幕中,当我创建稍后将传递给 WCF RIA 服务插入方法的对象时,我必须显式设置一个唯一 ID(然后这个值将是用底层数据库表中的唯一计数器 ID 覆盖)。

请参阅此项目的示例代码:http: //lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/157/A-Visual-Studio-LightSwitch-Picture-File-Manager.aspx

于 2012-10-18T05:19:58.070 回答