使用或不使用WCF轻松绑定dbcontext
本文关键字:绑定 dbcontext WCF | 更新日期: 2023-09-27 18:02:17
亲爱的程序员们,
我有一个问题无法解决,它更多地与我应该如何设计应用程序有关,直到现在,我一直通过编写大量代码来克服这个问题。
我必须设计一个连接到数据库的silverlight应用程序,出于多种原因,我希望在这两个应用程序之间使用WCF服务。
如果我使用WCF服务,我将失去dbcontext结构,当我们想使用CollectionViewSource和相关字段来绑定xaml控件时,这是非常好的
举个例子,假设我们有这样的简单实体,从edmx文件生成:电阻和电阻类别
public partial class ResistorCategories
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public ResistorCategories()
{
this.Name = "New";
this.ResistorsSet = new HashSet<ResistorsSet>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ResistorsSet> ResistorsSet { get; set; }
}
public partial class ResistorsSet
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public ResistorsSet()
{
this.ResistorStockEntriesSet = new HashSet<ResistorStockEntriesSet>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Resistance { get; set; }
public Nullable<decimal> PowerRating { get; set; }
public Nullable<decimal> Price { get; set; }
public Nullable<decimal> Tolerance { get; set; }
public string SupplierCode { get; set; }
public string ManufacturerCode { get; set; }
public int ResistorCategories_Id { get; set; }
public Nullable<int> Suppliers_Id { get; set; }
public Nullable<int> Manufacturers_Id { get; set; }
public virtual ResistorCategories ResistorCategories { get; set; }
public virtual Suppliers Suppliers { get; set; }
public virtual Manufacturers Manufacturers { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ResistorStockEntriesSet> ResistorStockEntriesSet { get; set; }
}
在xaml中,很容易放置2个数据网格,并查看属于以下类别的电阻器列表:
在xaml:中
然后我将每个数据网格绑定到其相应的CollectionViewSource:
ItemsSource="{Binding Source={StaticResource resistorCategoriesViewSource}, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={StaticResource resistorCategoriesResistorsViewSource}, UpdateSourceTrigger=PropertyChanged}"
在代码隐藏文件中,启用了lazyloading:
System.Windows.Data.CollectionViewSource resistorCategoriesViewSource =
((System.Windows.Data.CollectionViewSource)(this.FindResource("resistorCategoriesViewSource")));
//
_context.ResistorCategoriesSet.Load();
resistorCategoriesViewSource.Source = _context.ResistorCategoriesSet.Local;
因此,显示带有相关字段的记录再容易不过了,但在这种情况下,xaml客户端直接查询数据库,这正是我希望通过WCF服务避免的,同时添加一些标准化和安全性。
对于WCF,首先我必须使用EF Power Tool生成POCO对象,因为它的虚拟属性(即使我停用lazyloading和proxy(无法通过示例返回IEnumerable。然后,我必须查询并将POCO对象存储在分离的集合中:ObservableCollection&;ObservableCollection
然后,我将每个数据网格绑定到其集合,并监视selecteditem事件,以手动更改电阻器的数据网格中显示的集合!
所以我想有一个解决方案可以将WCF与dbcontext的简单性结合使用!请帮帮我!提前感谢
您可以实现自己的"数据提供程序",基于示例数据提供程序:Entity Framework 5 sample provider。但是,您需要"隧道"和串行化数据,以便通过wcf发送/接收。
谢谢你的留言,我想是的,最后我将不得不做这样的事情,我正在努力寻找一个简单的解决方案,但我想我想做的是不可能的。
与其试图通过绑定来节省时间,我应该专注于通过生成数据服务来节省时间。wcf数据服务是一个很好的解决方案,我也尝试过codetrigger,实际上我正在尝试用openria服务实现它。。。。。这似乎很糟糕!!
所以老实说,我不知道,我可以使用wcf数据服务来完成数据部分,但我希望silverlight应用程序也能在asp.net应用程序中检索当前已验证用户的姓名和角色,以便自定义UI。所以我想我必须使用第二个wcf服务。
我可能在做梦,但如果可能的话,我希望silverlight应用程序在用户登录或注销时收到通知,而不是一直查询asp.net应用程序。
如果我找到了一个解决方案,我当然会发布它,因为我认为当有人想写一个silverlight应用程序时,这是很常见的。
所以我终于找到了一个解决方案,即使这个解决方案很简单,也值得搜索:使用WCF数据服务。
可以查询具有所有相关实体的数据库,并将它们绑定到xaml:中
例如,考虑一个名为ItemsCategory的实体,它有一个通过ItemCategory_Id字段引用它的项目列表,另外两个名为ItemPrices和ItemImages的实体通过Item_Id字段引用项目:
- 项目类别
-
- 项目
-
-
- 分项价格
-
-
-
- 项目图像
-
它并不完美,但看起来像那样。
因此,如果你想为ItemsCategory放置一个数据网格,并在第二个数据网格中查看相关的Items,在xaml中的第三个和第四个数据网格查看相关的ItemPrices和ItemImages,你可以这样定义它:
<navigation:Page.Resources>
<CollectionViewSource x:Key="itemsCategoriesSetViewSource" d:DesignSource="{d:DesignInstance SvcCatalogDatabase:ItemsCategories, CreateList=True}"/>
<CollectionViewSource x:Key="itemsCategoriesSetItemsSetViewSource" Source="{Binding Items, Source={StaticResource itemsCategoriesSetViewSource}}"/>
<CollectionViewSource x:Key="itemsCategoriesSetItemsSetItemsPricesSetViewSource" Source="{Binding ItemsPrices, Source={StaticResource itemsCategoriesSetItemsSetViewSource}}"/>
<CollectionViewSource x:Key="itemsCategoriesSetItemsSetItemsImagesSetViewSource" Source="{Binding ItemsImages, Source={StaticResource itemsCategoriesSetItemsSetViewSource}}"/>
</navigation:Page.Resources>
要加载实体,您首先定义这样的集合:
public DataServiceCollection<ItemsCategories> ItemsCategoriesTracked { get; set; }
public CollectionViewSource ItemsCategories_CVSrc { get; set; }
要查询数据库,您只需要查询具有相关实体的ItemCategories:
ItemsCategories_CVSrc.Source = null;
ItemsCategoriesTracked.LoadAsync(this.SvcData.ItemsCategoriesSet.Expand("Items").Expand("Items/ItemsPrices,Items/ItemsImages"));
当然,您已经为DataServiceCollection的LoadCompleted事件定义了一个处理程序:
ItemsCategoriesTracked.LoadCompleted += new EventHandler<LoadCompletedEventArgs>((sender, e) => DataServiceCollection_LoadCompleted<ItemsCategories>(sender, e, ItemsCategories_CVSrc));
private void DataServiceCollection_LoadCompleted<T>(object sender, LoadCompletedEventArgs e, CollectionViewSource target)
{
if (e.Error == null)
{
if ((sender as DataServiceCollection<T>).Continuation != null)
{
(sender as DataServiceCollection<T>).LoadNextPartialSetAsync();
}
else
{
target.Source = (sender as DataServiceCollection<T>);
}
}
else
{
MessageBox.Show(string.Format("{0}: An error has occured: {1}", typeof(T).Name, e.Error.Message));
}
}
您已经将CollectionViewSource链接到XAML中定义的那个:
ItemsCategories_CVSrc = (CollectionViewSource)this.Resources["itemsCategoriesSetViewSource"];
瞧!希望它能帮助到别人!