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