【问题标题】:Entity Framework 5.0 and FileTable实体框架 5.0 和 FileTable
【发布时间】:2012-11-01 16:42:13
【问题描述】:

假设我的 SQL Server 2012 数据库中有以下表格:

Person
  PersonId
  FirstName
  LastName

Photo
  PhotoId
  PersonId (fk)
  DateTaken

PhotoFileTable
  (all the FileTable columns)

存储在磁盘上的照片结构如下: \\myserver\filestreamshare\People\PersonId\Photo1.tif

而且非常重要:磁盘上已经有大量照片需要添加到数据库中——这就是为什么我认为 FileTable 会很酷,因为它会自动提取它们。

所以我需要做两件事——首先,将 Photo 表与 PhotoFileTable 关联起来,这样我就可以获得一个人的所有照片。其次(也是更痛苦的)我想使用 Entity Framework 5.0 来做到这一点。

使用 edmx 设计器,我无法添加包含hierarchyid 的表。由于这是主键,因此它似乎应该用作 PhotoId 和 path_locator(FileTable hierarchyid)之间的 1:1 映射。但是我也无法添加照片表。

这里最好的方法是什么?归根结底,我想在 C# 中使用 EF 对象。理想情况下,它看起来像:

class Person
  List<Photo>

class Photo
  Filestream (to lazy load the image from the filesystem to bitmapimage)
  Path (?)

or maybe
class Photo
  BitmapImage (lazy load)

我是不是走错了路?我可以从这里到那里吗?想法或建议?

【问题讨论】:

    标签: c# sql entity-framework sql-server-2012 filetable


    【解决方案1】:

    也许你可以试试这个。

    表:

    PhotoTable(
    PhotoID uniqueidentifier ROWGUIDCOL  NOT NULL,
    PhotoImage varbinary(max) FILESTREAM  NULL,
    

    )

    插入:

    create procedure spPhotoInsert
       @PhotoID uniqueidentifier
       ,@sPhotoPath nvarchar(max)
       ,@PhotoImage varbinary(max)
     as
    begin
    
        select 
            cast('' as  varbinary(max)) PhotoImage
        into 
            #ret1
    
        truncate table #ret1
    
        declare @strSql nvarchar(max) = 'select * from OPENROWSET(BULK ''' 
                                        + @sPhotoPath + ''',SINGLE_BLOB) AS PhotoImage'
        insert into #ret1 EXEC(@strSql)
    
        insert into
            PhotoTable
               (
               PhotoID
               ,PhotoImage
               )
        select
            @PhotoID
            ,PhotoImage
        from
            #ret1
    
        drop table #ret1
    
    end
    

    更新:

    create procedure spPhotoUpdate
       @PhotoID uniqueidentifier
       ,@sPhotoPath nvarchar(max)
       ,@PhotoImage  varbinary(max)
    as
    begin
    
        select 
            cast('' as  varbinary(max)) PhotoImage
        into 
            #ret1
        truncate table #ret1
    
    
        declare @strSql nvarchar(max) = 'select * from OPENROWSET(BULK ''' 
                                        + @sPhotoPath + ''',SINGLE_BLOB) AS PhotoImage'
        insert into #ret1 EXEC(@strSql)
    
        update
            PhotoTable
        set
            PhotoImage = r.PhotoImage
        from
            PhotoTable, #ret1 r
        where
            PhotoID = @PhotoID
    
        drop table #ret1
    
    end
    

    删除:

    create procedure PhotoDelete
       @PhotoID uniqueidentifier
    as
    begin
    
        delete
            PhotoTable
        where
            PhotoID = @PhotoID
    
    end
    

    还有观点:

    CREATE VIEW vPhotoTable
    AS
        select
           PhotoID
           ,'' as sPhotoPath
           ,PhotoImage
        from 
            PhotoTable
    

    在此之后,可以使用 EF 读取/写入图像,如下所示:

    //InsertPhoto(sPath) 
    Entities db = new Entities();
    vPhoto p = db.vPhotos.CreateObject();
    p.PhotoID = Guid.NewGuid();
    p.sPhotoPath = sPath;
    db.vPhotos.AddObject(p);
    db.SaveChanges();
    
    //UpdatePhoto(PhotoID,sPath):
    Entities db = new Entities();
    vPhoto p = db.vPhotos.Where(x => x.PhotoID == PhotoID).Single();
    p.sPhotoPath = sPath;
    db.ObjectStateManager.ChangeObjectState(p, EntityState.Modified);
    db.SaveChanges();
    
    //DeletePhoto(PhotoID):
    Entities db = new Entities();
    vPhoto p = db.vPhotos.Where(x => x.PhotoID == PhotoID).Single();
    db.vPhotos.DeleteObject(p);
    db.SaveChanges();
    

    【讨论】:

    • 很好,谢谢!除了我在数据库中的表是 SQL 2012 FileTable,而不是 FileStream。所以问题仍然是如何在数据库端将这两个东西联系在一起。 SP 方法可能是正确的...
    • 我同意,很抱歉,但我没有意识到我们在谈论 SQL 2012。
    猜你喜欢
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多