2013-10-10 57 views
0

我正在用Entity Framework 4在VS2010 .NET4.0中构建一个简单的mvvm WPF应用程序。我是一个只有1年编程经验的WPF初学者。尝试将我的XAML中的数据网格绑定到实体框架模型。我的View Model中有一个可观察的集合,但似乎无法读取数据?带实体框架的WPF MVVM?

我有一个包含在项目中的实体框架.edmx,它包含一个带有主ID的单个“tbCountrys”表。

这里是刚刚宣布了一些变量/与我的表列的属性和实现INotifyPropertyChanged我的模型类:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ComponentModel; 

namespace Entity_MVVM 
{ 
public class CountrysModel : INotifyPropertyChanged 
{ 
    #region variables 

    private string _CountryId; 
    private string _ShortName; 
    private string _LongName; 

    # endregion 

    # region Properties 

    public string CountryId 
    { 
     get { return _CountryId; } 
     set { _CountryId = value; 
       OnPropertyChanged("CountryId"); 
     } 
    } 

    public string ShortName 
    { 
     get { return _ShortName; } 
     set 
     { 
      _ShortName = value; 
      OnPropertyChanged("ShortName"); 
     } 
    } 

    public string LongName 
    { 
     get { return _LongName; } 
     set 
     { 
      _LongName = value; 
      OnPropertyChanged("LongName"); 
     } 
    } 

    #endregion 

    # region INotifyPropertyChanged 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    # endregion 
    } 
} 

我的视图模型也实现INotifyPropertyChanged,宣称可观察集合来存储我的查询结果,有一个LoadGrid()方法,它应该用EntityConnection查询我的表并填充Observable集合。这似乎没有工作?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Data; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Data.EntityClient; 
using System.Data; 
using System.Windows; 
using System.Collections; 


namespace Entity_MVVM 
{ 
    public class CountrysViewModel : INotifyPropertyChanged 
    { 
    #region Constructor 

    public CountrysViewModel() 
    { 
     LoadGrid(); 
    } 

    # endregion 

    # region INotifyPropertyChanged 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    # endregion 

    # region ObservableCollection 

    private ObservableCollection<CountrysModel> _CountrysModelObservableList = new ObservableCollection<CountrysModel>(); 
    public ObservableCollection<CountrysModel> CountrysModelObservableList 
    { 
     get { return _CountrysModelObservableList; } 
     set 
     { 
      _CountrysModelObservableList = value; 
      OnPropertyChanged("CountrysModelObservableList"); 
     } 
    } 

    # endregion 

    # region Properties 

    private CountrysModel _CountrysModelView; 
    public CountrysModel CountrysModelView 
    { 
     get { return _CountrysModelView; } 
     set 
     { 
      _CountrysModelView = value; 
      OnPropertyChanged("CountrysModel"); 
     } 
    } 

    # endregion 

    # region LoadGrid Method 

    public void LoadGrid() 
    { 
     LDBEntities db = new LDBEntities(); 
     using (var conn = new EntityConnection("name=LDBEntities")) 
     { 
      conn.Open(); 
      EntityCommand cmd = conn.CreateCommand(); 
      cmd.CommandText = "SELECT * FROM LDBEntities.tbCountrys"; 

      try 
      { 
       EntityDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection); 

       _CountrysModelObservableList.Clear(); 

       while (rdr.Read()) 
       { 
        var cCountryId = rdr["CountryId"].ToString(); 
        var cShortName = rdr["shortName"].ToString(); 
        var cLongName = rdr["longName"].ToString(); 

        _CountrysModelView = new CountrysModel() 
        { 
         CountryId = cCountryId, 
         ShortName = cShortName, 
         LongName = cLongName 
        }; 

        _CountrysModelObservableList.Add(_CountrysModelView); 
       } 
      } 
      catch 
      { 
       MessageBox.Show(string.Format("Can't read in data!")); 
      } 
     } 

    #endregion 

     } 
    } 
    } 

最后,我的XAML视图:

<Window x:Class="Entity_MVVM.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:vm="clr-namespace:Entity_MVVM" 
     Title="MainWindow" Height="350" Width="525" 
     DataContext="{DynamicResource MyViewModel}"> 
    <Window.Resources> 
     <vm:CountrysViewModel x:Key="MyViewModel"/> 
    </Window.Resources> 
    <Grid> 
     <DataGrid Width="400" Height="127" Name="grdPublications" ItemsSource="{Binding Path=CountrysModelObservableList}"> 
     </DataGrid> 
    </Grid> 
</Window> 

当我调试的代码,在我的视图模型try块是我从我的视图模型的构造函数调用LoadGrid()方法未执行并引发catch异常。读取数据的while循环从不运行,因为它在声明EntityDataReader对象后退出。也许有一些不太正确的查询语法?

任何帮助将是最受赞赏的,因为我无法找到许多使用实体框架与MVVM的在线示例。由于

Also, getting this exception in the XAML, can't create an instance of my View Model. The connection string is correct in the App.config so not sure what's causing it...

而且,得到这个例外在XAML,不能创建我的视图模型的实例。连接字符串在App.config中是正确的,所以不知道是什么导致它...

+1

任何你为什么使用实体框架的原因 - 然后手摇你的SQL和使用数据读取器。为什么不直接使用LINQ查询实体上下文? –

+0

嗨理查德。我试图找出一个由已使用这种方法读取数据的离开开发人员编写的应用程序。我之前在一个代码隐藏的WPF应用程序中使用了LINQ,并且认为它更直接。 – Hardgraf

回答

2

你连接字符串看起来确实错了。 代码失败在EntityConnection构造

at System.Data.EntityClient.EntityConnection.ctor(String connectionString) 

所以这是这一行:

new EntityConnection("name=LDBEntities") 

什么样的连接字符串的是"name=LDBEntities"

我想你已经忘记从你的资源文件中获取连接字符串。

new EntityConnection(SomeResource.LDBEntities) 
+1

连接字符串是在App.config中用name =“LDBEntities”后跟实际字符串声明的。当然我不需要在c#中声明它? – Hardgraf

+0

我现在修复了这个问题,我的eSQL查询不正确,改为... conn.Open(); EntityCommand cmd = conn.CreateCommand(); cmd.CommandText =“SELECT VALUE c FROM LDBEntities.tbCountrys as c”; – Hardgraf

+0

不,您不需要复制连接串。您必须向构造函数提供资源LDBEntities的实际值。 –