Lightswitch实现在一个表被修改后修改另一个表

最近学校有课在教学Lightswith,他是微软出品的基于数据驱动和SilverLight的快速开发框架,虽然功能强大,界面美观而且操作方便,但是感觉局限性还是很多。

其中我们项目的食品出库单详情表

QQ截图20151218152732

这个表将记录某种food出库的数量,而我们的库存表如下

QQ截图20151218152953

那么我们的需求就是在out_detail这个表之后,要让Lightswitch对storage表中的对应food_id的库存记录进行数量的修改。

下面是解决方法

首先我们要在out_detail里面编写inserted的触发器,具体方法是打开out_detail表,然后点击编写代码,找到out_detail_inserted并单击。

QQ截图2015121815295

然后跳转到代码发现out_detail_inserted被创建,这个方法将在out_detail被添加项目后触发。

partial void out_detail_Inserted(out_detailItem entity)
{
           //some code
}

然后我们在当前项目中创建一个storageRecord类用来保存从出库的记录(从哪个库出的,该食物出多少)

public class storageRecord
{
    public int storage_id;
    public int quantity;

    public storageRecord(int storage_id, int quantity)
    {
        this.storage_id = storage_id;
        this.quantity = quantity;
    }
}

然后我们在刚才触发器的类中创建下面的属性,用来保存所有出库记录

List<storageRecord> change_record = new List<storageRecord>();

然后我们还在这个类中编写进行食物出库检查和记录出库数量的方法

private object checkStorage(out_detailItem entity)
{
    int quantity = entity.quantity;
    int food_id = entity.foodItem.id;
    List<storageRecord> current_record = new List<storageRecord>();

    var storage_record = from storage in this.DataWorkspace.foodBankData.storage
                         where storage.foodItem.id == food_id
                         orderby storage.expire
                         select storage;
    foreach (storageItem record in storage_record)
    {
        int total = 0;
        total = total + record.quantity;
        if (quantity > record.quantity)
        {
            storageRecord current = new storageRecord(record.id, record.quantity);
            current_record.Add(current);
            quantity = quantity - record.quantity;
        }
        else
        {
            storageRecord current = new storageRecord(record.id, quantity);
            current_record.Add(current);
            quantity = 0;
            break;
        }
    }
    if (quantity > 0)
    {
        return null;
    }
    return current_record;
}

如果我们当前food_id对应的库存足够该次出库,上面方法返回出库的记录,否则返回null

然后我们回到inserted,编写调用checkStorage的方法

partial void out_detail_Inserted(out_detailItem entity)
{
    var result = this.checkStorage(entity);
    if (result == null)
    {
        return;
    }

    change_record = (List<storageRecord>)result;

}

这里面我们将在checkStorage方法中获取的记录放在这个类的属性中,是为了在后面的Executed方法中调用。因为在inserted中不允许我们创建额外的数据库工作空间。

然后回到out_detail表的主界面,创建SaveChanges_Executed方法,该方法将在该数据集的操作完成后调用

QQ截图20151218154342

创建完成后,我们编写代码

partial void SaveChanges_Executed()
{
    foreach (storageRecord item in change_record)
    {
        foodBankDataService db = this.Application.CreateDataWorkspace().foodBankData;
        storageItem storage_item = (from storage in db.storage
                                    where storage.id == item.storage_id
                                    select storage).FirstOrDefault();
        storage_item.quantity -= item.quantity;
        db.SaveChanges();
    }
    if (change_record.Count > 0)
    {
        change_record.Clear();
    }
}

这里调用了this.Application.CreateDataWorkspace() 来创建一个新的数据库工作空间,来执行我们对storage表的update操作。至此该功能完成

 

C#中Array和ArrayList的区别及泛型

1. Array类型的变量在声明的同时必须进行实例化(至少的初始化数组的大小),而ArrayList可以只先声明。

2. Array只能存储同构的对象,ArrayList可以存储异构变量。

这里有一个装箱和拆箱的概念,在以后会用到:如将String,int等隐式转化为Object是装箱,将Object强制转化为string,int是拆箱。在向Arraylist添加数据的过程中,对象先被装箱为Object,需要调用时再拆箱为对应的对象。但在这个过程中,强制转化加上ArrayList的异构特性,可能导致很多问题。由此提出了泛型的概念。

3. 在CLR托管的存放方式.

Array是始终连续存放的,ArrayList不一定是。

4. 初始化大小

Array对象的初始化必须制定大小,且创建后的数组大小是固定的,而ArrayList的大小可以动态指定。

关于泛型:

ArrayList是一个非泛型集合类,添加到ArrayList中的任何引用或值类型都将隐式向上强制转换为Object,如果项是值类型,则必须在将其添加到列表中是进行装箱操作。

泛型是最常见的用途是创建集合类。.Net Framework类库在Collection.Generic命名空间中包含ijge泛型集合类。List<T>类是ArrayList类的泛型等效类。使用大小可以按需动态增加的数组实现IList泛型接口。动态数组的好处是不必须事先设置较大的数组,减少不必要的内存开销。