我如何在WCF RIA服务中为LightSwitch创建一个一对一的关系?

本文关键字:一个 一对一 关系 创建 LightSwitch WCF RIA 服务 | 更新日期: 2023-09-27 18:04:45

我对WCF RIA Services和Microsoft LightSwitch的理解已经走了很长一段路,但现在我不知所措。我以AnimalDog为例。我实际上想要一个 0或1 对1的关系,不是每个动物都必须/有狗。

首先,我在我的数据库中创建了一个我想与RIA服务一起使用的一对一关系。然后更新模型。edmx文件在我的RIA服务项目像往常一样。问题是,这并没有像我期望的那样让我获得ObjectContext.Dogs,这并不存在,而是动物被赋予了狗的额外属性。显然,一对一的关系是专门以这种方式处理的,似乎是有意为之提供帮助的,但我在用这种方式处理它时遇到了很多困难。

我的RIA Services类是这样的:

public class RiaDog
{
    [Key]
    public int Id { get; set; }
    public int PackLeaderId { get; set; }
    [Association("RiaAnimal_RiaDog", "Id", "Id", IsForeignKey = true)]
    public RiaAnimal Animal { get; set; }
}
public class RiaAnimal
{
    [Key]
    public int Id { get; set; }
    [Association("RiaAnimal_RiaDog", "Id", "Id", IsForeignKey = false)]
    public RiaDog Dog { get; set; }
}

除非有某种我不知道的神奇的一对一数据注释属性,否则我必须为RiaDog编写CRUD方法,就像RiaAnimal和其他所有类一样。考虑到ObjectContext。狗不存在,我必须通过Animal:

[Query(IsDefault = true)]
public IQueryable<RiaDog> GetAllDogs() {
    var report = from animal in ObjectContext.Animals
                    where animal.PackLeader != null
                    select new RiaDog
                    {
                        Id = animal.Id,
                        PackLeaderId = animal.Dog.PackLeaderId,
                    };
    return report;
}

这已经感觉很奇怪了,我必须在Dog属性Animal被赋予的其中一个属性上使用where子句来隔离狗。

用一些简单的创意,我可以得到插入、更新和删除方法的功能:

public void InsertDog(RiaDog riaDog) {
    var animal = ObjectContext.Animals.FirstOrDefault(a => a.Id == riaDog.Id);
    animal.PackLeader = ObjectContext.PackLeaders.FirstOrDefault(pl => pl.Id == riaDog.PackLeaderId);
    riaDog.Animal.Dog = riaDog;
}
public void UpdateDog(RiaDog rd) {
    var animal = ObjectContext.Animals.FirstOrDefault(a => a.Id == riaDog.Id);
    animal.PackLeader = ObjectContext.PackLeaders.FirstOrDefault(pl => pl.Id == riaDog.PackLeaderId);
}
public void DeleteDog(RiaDog rd) {
}

UpdateAnimal()中,我使用我在InsertDog()中设置的背景引用,并添加:

if (riaAnimal.Dog == null)
    riaAnimal.PackLeader = null;

我也有狗设置级联删除与动物在数据库上。

在LightSwitch前端,我在RiaDog实体上添加了如下内容:

partial void AnimalType_Changed() {
    if (AnimalType != null && AnimalType.Name == "Dog" && this.Dog == null)
        this.Dog == new RiaDog();
    else if (this.Dog != null && (AnimalType == null || AnimalType.Name != "Dog"))
        this.Dog = null;
}

我遇到的问题是,如果我将类型更改为Dog,保存,将其更改回其他类型,保存,然后再次更改为Dog并保存,我收到错误:The context is already tracking a different entity with the same resource Uri.


我已经学会处理其他跟踪错误:

  • 当实体在后台代码客户端创建时,它们需要

  • 在WCF RIA Services中的任何插入方法中,实体的客户端id必须在数据库生成后设置为真实id,例如:

,

public void InsertRiaEntity(RiaEntity re) {
    var entity = new Entity();
    entity.SomeProperty = re.SomeProperty;
    entity.AnotherProperty = re.AnotherProperty;
    ObjectContext.Entities.AddObject(entity);
    ObjectContext.SaveChanges();
    // essential for client<->server tracking
    re.Id = entity.Id;
}

然而,我不知道如何解决这个电流跟踪错误。我真的觉得我采取了错误的方法,我正在寻找专家的建议,关于如何在WCF RIA服务中为Microsoft LightSwitch编写一对一或一或零对一关系。

我实际上已经设法得到这一切工作与一个多对多的关系,并在简短和合理的足够的代码,它似乎是"正确的",所以这种变化应该是可以实现的

我如何在WCF RIA服务中为LightSwitch创建一个一对一的关系?

LightSwitch实际上并不支持一对一的关系,所以即使你的RIA服务成功了,它也不会在LightSwitch中工作。

解决方法是创建一个具有0对多或一对多多重性的关系(正如您最终所做的那样)。您必须在验证或代码中"强制"一对一。