linq一对多关系只存储列表中的一个成员



我正试图在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;

我只得到第一个电话号码是111111。有趣的是,在第二次运行时,文本字符串包含"111111"one_answers"222222"。这是因为第二个人保存第二个电话号码,第三个人保存第三个电话号码等等。因此,如果你经常这样做,你会得到:111111222222333333111111222222333333。。。顺便说一句,如果您使用调试器跳转到"db.person.InsertOnSubmit(person);"看看"person",里面有一个包含所有三个数字的列表。所以它应该有效。。。

我真的很努力,但我想不出一个办法把它做好。不过,我的怀疑在于[协会]的性质。

这里有一个指向来源的链接,如果你想的话,你可以得到整个图片:https://docs.google.com/file/d/0B5G4zya_BlZyUlU0azVvbVdiajA/edit?usp=sharing

我不久前也遇到了这个问题。我在代码中添加了几行,使它消失了。

Linq2SQL有点神奇,有时事情(不)无缘无故地工作。只是为了完全确定你可能想要实现微软提供的官方一对多解决方案:

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上下文中添加选项,以强制深度对象加载:

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

相关内容

  • 没有找到相关文章

最新更新