C# Azure数据库和照片
我在Azure中建立了一个数据库,连同其他一些数据类型,它将容纳一些图片。保存照片的列是图像数据类型。我的插入看起来像这样(将pic转换为二进制文件)C# Azure数据库和照片,c#,image,azure,C#,Image,Azure,我在Azure中建立了一个数据库,连同其他一些数据类型,它将容纳一些图片。保存照片的列是图像数据类型。我的插入看起来像这样(将pic转换为二进制文件) 插入工作,当我在Azure中检查我的表时,在Picture列中插入一个二进制值。如何取回它,以及如何在我的WPF界面中显示实际照片?我同意@CSharpRocks的观点,因为您已经在使用Azure,所以进行一些研究并将图片存储到BlobStorage存储帐户将非常方便。与传统的数据库存储相比,存储帐户具有许多优势 您可以找到有关存储帐户以及如何开
插入工作,当我在Azure中检查我的表时,在Picture列中插入一个二进制值。如何取回它,以及如何在我的WPF界面中显示实际照片?我同意@CSharpRocks的观点,因为您已经在使用Azure,所以进行一些研究并将图片存储到BlobStorage存储帐户将非常方便。与传统的数据库存储相比,存储帐户具有许多优势 您可以找到有关存储帐户以及如何开始使用存储帐户的更多信息 但这个问题更多的是关于如何检索图像并根据您自己的问题在WPF应用程序中显示它。让我们看看: 您的图像已经存储在数据库中,因此可以使用主键值(或任何其他查询)获取相关的
tblShip
实体:
假设您在xaml视图中的某个地方有这样的内容:
<Image Name="imgControl" ... />
private void DisplayImageFromDb(Guid id)
{
using (var context = new DataContext())
{
var item = context
.tblShips
.AsNoTracking()
.FirstOrDefault(x => x.Id == id);
if (item == null)
throw new Exception("Image could not be found!");
//Convert the byte[] to a BitmapImage
BitmapImage img = new BitmapImage();
MemoryStream ms = new MemoryStream(item.Picture);
img.BeginInit();
img.StreamSource = ms;
img.EndInit();
//assign the image to the Source property of the Image Control.
imgControl.Source = img;
}
}
<Windows.Resources>
<local:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter" />
</Window.Resources>
using System;
using System.Globalization;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;
namespace WpfApp1
{
public class ByteArrayToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return null;
//Convert the byte[] to a BitmapImage
BitmapImage img = new BitmapImage();
MemoryStream ms = new MemoryStream((byte[])value);
img.BeginInit();
img.StreamSource = ms;
img.EndInit();
return img;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
这将正常工作,但如果您使用更面向WPF(MVVM)的方式,效果会更好。假设您有xaml视图,但您的视图使用的是MVVM。因此,图像控件绑定到viewmodel属性:
<Image Grid.Row="1"
Source="{Binding ImageSource, Converter={StaticResource ByteArrayToImageConverter}}"/>
现在,您有了一个清晰的关注点分离,因此您的UI就是实际显示图像的用户,而您的viewmodel应该只从数据库加载图像并操作域实体:
viewmodel必须声明用于绑定的ImageSource属性:
private byte[] imageSource;
public byte[] ImageSource
{
get { return imageSource; }
set
{
imageSource = value;
//must implement property changed notifications
OnPropertyChanged(new PropertyChangedEventArgs("ImageSource"));
}
}
在所有这些重构之后,viewmodel中加载图像的方法可以如下实现:
private void DisplayImageFromDb(int id)
{
using (var context = new DataContext())
{
var item = context
.tblShips
.AsNoTracking()
.FirstOrDefault(x => x.Id == id);
if (item == null)
throw new Exception("Image could not be found!");
//Assign the property and let the binding do the work
ImageSource = item.Picture;
}
}
你肯定会得到同样的结果,但你现在有了一个非常独立的应用程序,随着它的发展,可以更容易地进行维护
希望这有帮助 我同意@CSharpRocks的说法,因为您已经在使用Azure,所以您可以非常方便地进行一些研究并将图片存储在BlobStorage存储帐户中。与传统的数据库存储相比,存储帐户具有许多优势 您可以找到有关存储帐户以及如何开始使用存储帐户的更多信息 但这个问题更多的是关于如何检索图像并根据您自己的问题在WPF应用程序中显示它。让我们看看: 您的图像已经存储在数据库中,因此可以使用主键值(或任何其他查询)获取相关的
tblShip
实体:
假设您在xaml视图中的某个地方有这样的内容:
<Image Name="imgControl" ... />
private void DisplayImageFromDb(Guid id)
{
using (var context = new DataContext())
{
var item = context
.tblShips
.AsNoTracking()
.FirstOrDefault(x => x.Id == id);
if (item == null)
throw new Exception("Image could not be found!");
//Convert the byte[] to a BitmapImage
BitmapImage img = new BitmapImage();
MemoryStream ms = new MemoryStream(item.Picture);
img.BeginInit();
img.StreamSource = ms;
img.EndInit();
//assign the image to the Source property of the Image Control.
imgControl.Source = img;
}
}
<Windows.Resources>
<local:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter" />
</Window.Resources>
using System;
using System.Globalization;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;
namespace WpfApp1
{
public class ByteArrayToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return null;
//Convert the byte[] to a BitmapImage
BitmapImage img = new BitmapImage();
MemoryStream ms = new MemoryStream((byte[])value);
img.BeginInit();
img.StreamSource = ms;
img.EndInit();
return img;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
这将正常工作,但如果您使用更面向WPF(MVVM)的方式,效果会更好。假设您有xaml视图,但您的视图使用的是MVVM。因此,图像控件绑定到viewmodel属性:
<Image Grid.Row="1"
Source="{Binding ImageSource, Converter={StaticResource ByteArrayToImageConverter}}"/>
现在,您有了一个清晰的关注点分离,因此您的UI就是实际显示图像的用户,而您的viewmodel应该只从数据库加载图像并操作域实体:
viewmodel必须声明用于绑定的ImageSource属性:
private byte[] imageSource;
public byte[] ImageSource
{
get { return imageSource; }
set
{
imageSource = value;
//must implement property changed notifications
OnPropertyChanged(new PropertyChangedEventArgs("ImageSource"));
}
}
在所有这些重构之后,viewmodel中加载图像的方法可以如下实现:
private void DisplayImageFromDb(int id)
{
using (var context = new DataContext())
{
var item = context
.tblShips
.AsNoTracking()
.FirstOrDefault(x => x.Id == id);
if (item == null)
throw new Exception("Image could not be found!");
//Assign the property and let the binding do the work
ImageSource = item.Picture;
}
}
你肯定会得到同样的结果,但你现在有了一个非常独立的应用程序,随着它的发展,可以更容易地进行维护
希望这有帮助 这里的所有内容都是硬编码的,但下面是我移动100 x 100像素图像的方法 进出数据库。我知道有更好的方法来存储图像,但就我而言,这非常有效
public void InsertPhotoToDb()
{
string filepath = "C:\\TFS\\Enterprise.jpg";
byte[] Pic = File.ReadAllBytes(filepath);
ArmadaDataContext oDc = new ArmadaDataContext();
tblPictureTest otblPictureTest = new tblPictureTest();
otblPictureTest.Id = Guid.NewGuid();
otblPictureTest.FileName = "Enterprise";
otblPictureTest.Photo = Pic;
oDc.tblPictureTests.InsertOnSubmit(otblPictureTest);
oDc.SubmitChanges();
oDc = null;
}
private void DisplayImageFromDb()
{
using (var oDc = new ArmadaDataContext())
{
var item = oDc
.tblPictureTests
.FirstOrDefault(x => x.FileName == "Enterprise"); // Retrieves using the filename
// If retrieving using the GUID, use the line below instead.
// .FirstOrDefault(x => x.Id == Guid.Parse("58b44a51-0627-43fe-9563-983aebdcda3a"));
if (item == null)
throw new Exception("Image could not be found!");
//Convert the byte[] to a BitmapImage
BitmapImage img = new BitmapImage();
MemoryStream ms = new MemoryStream(item.Photo.ToArray());
img.BeginInit();
img.StreamSource = ms;
img.EndInit();
//assign the image to the Source property of the Image box in the UI.
imgPhoto.Source = img;
}
}
这里所有的东西都是硬编码的,但这里是我移动100 x 100像素图像的方式 进出数据库。我知道有更好的方法来存储图像,但就我而言,这非常有效
public void InsertPhotoToDb()
{
string filepath = "C:\\TFS\\Enterprise.jpg";
byte[] Pic = File.ReadAllBytes(filepath);
ArmadaDataContext oDc = new ArmadaDataContext();
tblPictureTest otblPictureTest = new tblPictureTest();
otblPictureTest.Id = Guid.NewGuid();
otblPictureTest.FileName = "Enterprise";
otblPictureTest.Photo = Pic;
oDc.tblPictureTests.InsertOnSubmit(otblPictureTest);
oDc.SubmitChanges();
oDc = null;
}
private void DisplayImageFromDb()
{
using (var oDc = new ArmadaDataContext())
{
var item = oDc
.tblPictureTests
.FirstOrDefault(x => x.FileName == "Enterprise"); // Retrieves using the filename
// If retrieving using the GUID, use the line below instead.
// .FirstOrDefault(x => x.Id == Guid.Parse("58b44a51-0627-43fe-9563-983aebdcda3a"));
if (item == null)
throw new Exception("Image could not be found!");
//Convert the byte[] to a BitmapImage
BitmapImage img = new BitmapImage();
MemoryStream ms = new MemoryStream(item.Photo.ToArray());
img.BeginInit();
img.StreamSource = ms;
img.EndInit();
//assign the image to the Source property of the Image box in the UI.
imgPhoto.Source = img;
}
}
您应该探索将图像存储在Blob存储中的可能性,只需将其id或路径存储在数据库中即可。存储成本要便宜得多。您应该探索将图像存储在Blob存储中的可能性,只需将其id或路径存储在数据库中即可。存储成本要便宜得多..AsNoTracking()给出一个红色的曲线,请求程序集引用或指令。我添加了System.Data.Entity;System.Data.Linq;还是不行。@Coolhand你可以安全地移除这条线。我已经使用EF DbContext测试了它,而您似乎正在使用另一种datacontext。我的datacontext来自我的dbml。我不知道EF DbContext是什么。我删除了.AsNoTracking(),它就像一个符咒!谢谢AsNoTracking()给出一个红色的波形,请求程序集引用或指令。我添加了System.Data.Entity;System.Data.Linq;还是不行。@Coolhand你可以安全地移除这条线。我已经使用EF DbContext测试了它,而您似乎正在使用另一种datacontext。我的datacontext来自我的dbml。我不知道EF DbContext是什么。我删除了.AsNoTracking(),它就像一个符咒!谢谢