C# Azure数据库和照片

C# Azure数据库和照片,c#,image,azure,C#,Image,Azure,我在Azure中建立了一个数据库,连同其他一些数据类型,它将容纳一些图片。保存照片的列是图像数据类型。我的插入看起来像这样(将pic转换为二进制文件) 插入工作,当我在Azure中检查我的表时,在Picture列中插入一个二进制值。如何取回它,以及如何在我的WPF界面中显示实际照片?我同意@CSharpRocks的观点,因为您已经在使用Azure,所以进行一些研究并将图片存储到BlobStorage存储帐户将非常方便。与传统的数据库存储相比,存储帐户具有许多优势 您可以找到有关存储帐户以及如何开

我在Azure中建立了一个数据库,连同其他一些数据类型,它将容纳一些图片。保存照片的列是图像数据类型。我的插入看起来像这样(将pic转换为二进制文件)


插入工作,当我在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(),它就像一个符咒!谢谢