linq一对多关系店只有一个列表成员

时间:2013-08-22 09:51:37

标签: c# linq windows-phone-8 one-to-many entityset

我试图在Windows Phone 8上与linq建立一对多的关系。 我的问题是在EntitySet<>字段只应该存储的类之一,真正存储到数据库中。 所以我做了一个简单的项目,为您提供我的问题的线索。 Person和Number有两个类。一个人可以有很多数字。

这是数字类:

[Table]
class Number
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int NumberID { get; set; }

    [Column]
    public int PhoneNumber { get; set; }

}

Person类:

[Table]
class Person
{
    private EntitySet<Number> numbers = new EntitySet<Number>();

    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int PersonID { get; set; }

    [Column]
    public string Name { get; set; }

    [Association(Storage = "numbers", ThisKey = "PersonID", OtherKey = "NumberID")]
    public EntitySet<Number> Numbers
    {
        get { return numbers; }
        set
        {
            numbers.Assign(value);
        }
    }
}

当我现在尝试插入一个有三个数字的人时:

        EntitySet<Number> numbers = new EntitySet<Number>();
        DataBase db = new DataBase(App.DBConnectionString);
        Number num1 = new Number() { PhoneNumber = 111111 };
        Number num2 = new Number() { PhoneNumber = 222222 };
        Number num3 = new Number() { PhoneNumber = 333333 };
        Person person = new Person() { Name = "Donald" };
        numbers.Add(num1);
        numbers.Add(num2);
        numbers.Add(num3);
        person.Numbers = numbers;


        try
        {
            db.Persons.InsertOnSubmit(person);
            db.SubmitChanges();
        }
        catch (Exception s)
        {
            // do nothing
        }

然后尝试再次检索数据:

        DataBase db = new DataBase(App.DBConnectionString);
        string text = "";
        foreach (Person person in db.Persons)
        {
            foreach (Number num in person.Numbers)
            {
                text += num.PhoneNumber + System.Environment.NewLine;
            }
        }

        TextBlock.Text = text;

我只收到第一个电话号码是&#39; 111111&#39;。有趣的是,在第二次运行中,文本字符串包含&#11; 111111&#39;和&#39; 222222&#39;。这是因为在第二个人中保存了第二个电话号码,在第三个人中保存了第三个电话号码,依此类推。 因此,如果您经常这样做,您会得到: 111111 222222 333333 111111 222222 333333 ... 顺便说一句,如果你使用调试器跳转到&#39; db.Persons.InsertOnSubmit(person);&#39;并调查“人”#39;有一个包含所有三个数字的列表。所以它应该有用......

我努力尝试,但我无法找到一种方法来解决问题。我怀疑是在[Association]属性上。

以下是指向来源的链接,以便您可以根据需要全面了解:https://docs.google.com/file/d/0B5G4zya_BlZyUlU0azVvbVdiajA/edit?usp=sharing

1 个答案:

答案 0 :(得分:1)

前一段时间我也遇到过这个问题。我在代码中添加了几行,使其消失。

Linq2SQL有点神奇,有时事情(不)没有明显的原因。只是为了完全确定您可能希望实现Microsoft提供的官方一对多解决方案:

http://msdn.microsoft.com/en-us/library/vstudio/bb386950(v=vs.100).aspx

我还会做出以下调整:

[Table]
class Number
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int NumberID { get; set; }

    [Column]
    public int _personID { get; set; }

    [Column]
    public int PhoneNumber { get; set; }

    private EntityRef<Person> _person;
    [Association(Storage = "_person", ThisKey = "_personID", OtherKey = "PersonID", IsForeignKey = true)]
    public Person Person
    {
        get { return this._person.Entity; }
        set { 
            this._person.Entity = value;
            if (value != null)
            {
                this._personID = value.PersonID;
            }
        }
    }  
}

我将其添加到构造函数中:

public Person()
{
    this._numbers = new EntitySet<Number>(
    delegate (Number entity)
    {
        entity.Person = this;
    },
    delegate (Number entity)
    {
        entity.Person = null;
    });
}

作为测试,我不会尝试加载整个对象。首先,检查所有数字是否已进入数据库:

var numbers = db.Numbers.ToList();

这是因为Windows Phone上的L2S在读取深层对象连接时遇到了严重问题。一个级别很好,但更深层次的关系被忽略。因此,如果您的Person类驻留在另一个可能也存在问题的类中。

编辑:您可以向数据库上下文添加选项,以强制进行深层对象加载:

_db = new DBContext("isostore:/mydb.sdf");
DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Person>(p => p.Numbers);
_db.LoadOptions = loadOptions;