如何使用EF在WPF DataGrid中创建可编辑数据?

时间:2014-01-12 11:34:07

标签: wpf entity-framework wpfdatagrid

我正在使用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();

但这会使数据变为只读。那么,我如何才能实现数据的“可编辑性”?查询返回的数据应该以某种方式与底层实体相关,但无法弄清楚。拜托,帮我解决这个问题!先谢谢!

1 个答案:

答案 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;
        }
    }