Simple.Data多对多问题

时间:2012-02-29 17:29:11

标签: asp.net-mvc-3 many-to-many simple.data

所以我正在研究我希望的数据库的简化示例,该数据库包含以下表格:

Contractors: Id, ContractorName
Types: Id, TypeName
CoverageZips: ContractorId, Zip
TypesForContractors: ContractorId, TypeId

承包商可以拥有许多拉链,类型和类型,拉链可以有许多承包商(多对多)。

我正在努力:

  1. 以特定邮政编码搜寻承包商
  2. 然后为这些承包商加载类型。
  3. 第一部分的SQL可能如下所示:

    SELECT * FROM dbo.Contractors WHERE Id IN
    (SELECT ContractorId FROM dbo.CoverageZips WHERE Zip = 12345)
    

    这是我在Simple.Data的第一部分所拥有的。它工作正常,但我觉得我错过了一些Simple.Data的美......

    List<int> contractorIds = new List<int>();
    foreach(var coverage in _db.CoverageZips.FindAllByZip(zip)) {
        contractorIds.Add((int)coverage.ContractorId);
    }
    var contractors = new List<dynamic>();
    if (contractorIds.Count > 0) {
        contractors = _db.Contractors.FindAllById(contractorIds).ToList<dynamic>();
    }
    return contractors;
    

    在我尝试第2部分之前,这工作正常:

    public dynamic GetAllForZip(int zip) {
        List<int> contractorIds = new List<int>();
        foreach(var coverage in _db.CoverageZips.FindAllByZip(zip)) {
            contractorIds.Add((int)coverage.ContractorId);
        }
        var contractors = new List<dynamic>();
        if (contractorIds.Count > 0) {
            contractors = _db.Contractors.FindAllById(contractorIds).ToList<dynamic>();
        }
        foreach (var contractor in contractors) {
            // Exception occurs here on second iteration
            // even though the second contractor was originally in the contractors variable
            contractor.types = GetTypesForContractor((int)contractor.Id);
        }
        return contractors;
    }
    
    public dynamic GetTypesForContractor(int id) {
        var types = new List<dynamic>();
        if (id > 0) {
            List<int> typeIds = new List<int>();
            foreach (var typeForContractor in _db.TypesForContractor.FindAllByContractorId(id)) {
                typeIds.Add((int)typeForContractor.TypeId);
            }
    
            if (typeIds.Count > 0) {
                types = _db.ContractorTypes.FindAllById(typeIds).ToList<dynamic>();
            }
        }
        return types;
    }
    

    我设置了一个断点,第一次迭代显示的一切正常,但在第二次失败时出现以下异常:

    指数超出范围。必须是非负数且小于集合的大小。

    TL;博士

    我不确定如何正确使用与Simple.Data的多对多关系,并且当我多次尝试我的方法时会发生一些奇怪的事情

1 个答案:

答案 0 :(得分:5)

我不知道该异常发生了什么,今天将进行调查。

但是,你错过了一些美貌。假设您在数据库上配置了参照完整性(当然可以这样做;)),您的方法可以这样编写:

public dynamic GetAllForZip(int zip) {
    var contractors = _db.Contractors
        .FindAll(_db.Contractors.ContractorZips.Zip == zip)
        .ToList();

    foreach (var contractor in contractors) {
        contractor.Types = GetTypesForContractor((int)contractor.Id);
    }
    return contractors;
}

public dynamic GetTypesForContractor(int id) {
    return _db.ContractorTypes
        .FindAll(_db.ContractorTypes.TypesForContractor.ContractorId == id)
        .ToList();
}

更新!

从1.0.0-beta3开始,支持多对多连接的急切加载,所以现在你可以这样做:

public dynamic GetAllForZip(int zip) {
    return _db.Contractors
        .FindAll(_db.Contractors.ContractorZips.Zip == zip)
        .With(_db.Contractors.TypesForContractor.ContractorTypes.As("Types"))
        .ToList();
}

它作为单个SQL选择执行,使您的DBA像彩虹小猫一样快乐。