我正在使用EF6 Code First和WPF DataGrid。 比方说,我有两列,T1和T2,一对一的关系:
-- Create tables.
-- This is the parent table.
create table dbo.T1
(
id int primary key,
addr varchar(100) not null
);
-- This is the child table.
create table dbo.T2
(
id int primary key,
name varchar(100) not null
);
-- Set primary "id" column of T2 as foreign key.
alter table dbo.T2
add constraint T1_pk
foreign key (id) references dbo.T1(id);
-- Insert some sample values
insert into dbo.T1 values (1, 'addr1'), (2, 'addr2'), (3, 'addr3');
insert into dbo.T2 values (1, 'name1'), (2, 'name2');
我希望1)显示来自T2子表的DataGrid中的所有列以及来自父T1表的一些列,如下面的SQL表示,以及2)使此数据可编辑:
select T1.id, T1.addr, T2.name
from dbo.T1 left join dbo.T2 on T1.id = T2.id;
我用以下内容解决了问题的第一部分:
var query = from r1 in db.T1
join r2 in db.T2 on r1.id equals r2.id into gj
from x in gj.DefaultIfEmpty()
select new
{
r1.id,
r1.addr,
name = (x == null ? string.Empty : x.name)
};
query.Load();
dg.ItemsSource = null;
dg.ItemsSource = query.ToList();
但这会使数据变为只读。那么,我如何才能实现数据的“可编辑性”?查询返回的数据应该以某种方式与底层实体相关,但无法弄清楚。拜托,帮我解决这个问题!先谢谢!
答案 0 :(得分:0)
请尝试将查询结果打包到特殊的联接类中 像这样
var query = from r1 in db.T1
join r2 in db.T2 on r1.ID equals r2.ID into gj
from x in gj.DefaultIfEmpty()
select new {T1 = r1, T2 = x};
dg.ItemsSource = new ObservableCollection<JoinT1T2Class>(query.ToList().Select(n=>new JoinT1T2Class(n.T1,n.T2)));
//Here is editable DataSource;
public class JoinT1T2Class
{
private T1 _T1;
private T2 _T2;
public JoinT1T2Class(T1 t1, T2 t2)
{
this._T1 = t1;
this._T2 = t2;
}
public int ID { get { return _T1.ID; } }
public string Addr { get { return _T1!=null?_T1.Addr:string.Empty; } set { if (_T1!=null)_T1.Addr = value; } }
public string Name { get { return _T2!=null?_T2.Name:string.Empty; } set { if(_T2!=null)_T2.Name = value; } }
}
其中T1和T2是您的实体类。
public class T1
{
[Key]
[Column("id")]
public int ID { get; set; }
[Column("addr")]
public string Addr { get; set; }
}
public class T2
{
[Key]
[Column("id")]
public int ID { get; set; }
[Column("name")]
public string Name {get;set;}
}
为了能够将更改存储到DataBase中,您已将DataContext的引用保存在私有变量中,并将其置于窗口关闭状态;
要保存所有更改,您必须调用db.SaveChanges();
如果需要处理添加或删除行
,请使用CollectionChanged事件处理程序ObservableCollection<JoinT1T2Class> dataSource = new ObservableCollection<JoinT1T2Class>(query.ToList().Select(n=>new JoinT1T2Class(n.T1,n.T2)));
dataSource.CollectionChanged += dataSource_CollectionChanged;
void dataSource_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
// to access added items use e.NewItems
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
// to access deleted items use e.OldItems
break;
}
}