Thursday, October 20, 2016

Sql Server Filetable and Entity Framework





CREATE PROCEDURE SFilesDelete (@fId uniqueidentifier)
AS
BEGIN
SET NOCOUNT ON;
DELETE from SFiles where stream_id = @fId;  
END
GO

ALTER PROCEDURE [dbo].[SFilesInsert]
@fname nvarchar(255)
,@fData varbinary(max)
AS
BEGIN

Declare @fid uniqueidentifier = NEWID();
    INSERT INTO SFiles (stream_id, file_stream, name) VALUES (@fId ,@fdata,@fname);
    SELECT stream_id, file_stream.PathName() as unc_path FROM SFiles where stream_id = @fId
END

Entity Framework Code First Alter Database for FileTable

if (not exists (select * from sys.filegroups where name ='FStream'))
begin
declare @FilePathAndName nvarchar(4000)= (select physical_name FROM sys.master_files where database_id=db_ID() and file_id=1)
set @FilePathAndName= REPLACE(@FilePathAndName,'.mdf','_FileStream.fs')
--print @FilePathAndName
declare @sqlStr as nvarchar(max) ='alter database ' + db_name() +' ADD FILEGROUP FStream CONTAINS FILESTREAM'+CHAR(13)
set @sqlStr = @sqlStr  + 'ALTER DATABASE ' + db_name() +' ADD FILE ( NAME = N''FStream'', FILENAME = N'''+@FilePathAndName +''' ) TO FILEGROUP fStream'+CHAR(13)
set @sqlStr = @sqlStr  + 'ALTER DATABASE ' + db_name() +' SET FILESTREAM (NON_TRANSACTED_ACCESS = FULL, DIRECTORY_NAME = N'''+db_name()+'FilesDir'')'+CHAR(13)
set @sqlStr = @sqlStr + 'CREATE TABLE dbo.MyFiles AS FILETABLE WITH ( FILETABLE_DIRECTORY = ''MyFileDir'')'+CHAR(13)
print @sqlStr
exec (@SqlStr)
end

Tuesday, October 18, 2016

Sql Server Filetable (since 2012)

1.) Filestream TSQL

A) Pepare SQL Server

1) configuration Manager / SQL-Server Db Service Propteries / Filestream Tab: Check all
2) EXEC sp_configure filestream_access_level, 2  RECONFIGURE
3) restart SQL Server Service

B) Prepare DATABASE

ALTER DATABASE testFileTable SET FILESTREAM (NON_TRANSACTED_ACCESS = FULL, DIRECTORY_NAME = N'FilesDir')

alter database testFileTable  ADD FILEGROUP fsg CONTAINS FILESTREAM;
ALTER DATABASE testFileTable  ADD FILE ( NAME = N'fsf', FILENAME = N'D:\sqlData\filesteamtest\' ) TO FILEGROUP fsg;
ALTER DATABASE testFileTable  SET READ_COMMITTED_SNAPSHOT OFF WITH NO_WAIT;


C) Prepare TABLE

CREATE TABLE dbo.MyFiles AS FILETABLE
WITH
(
FILETABLE_DIRECTORY = 'MyFilesDir',
FILETABLE_COLLATE_FILENAME = database_default
)


D) Write Files

just drag them into the filetabledir - get UNC Path of it:
SELECT FileTableRootPath('TestFileTable') AS FileTableRootPath

or
INSERT INTO [dbo].[FileTableTb] ([name],[file_stream])SELECT'NewFile.txt', * FROM OPENROWSET(BULK N'd:\NewFile.txt'SINGLE_BLOBAS FileData
or
INSERT INTO [dbo].StpFile ([name],[file_stream]) SELECT 'test1.txt', CONVERT(VARBINARY(MAX),'TestFileText') AS FileData

create Dir:
INSERT INTO FileTableTb (name, is_directory)   VALUES ('testFolder', 1)

GO


create file in subdir: have to get pathlocator first:

select GetPathLocator(CONCAT(FileTableRootPath('FileTableTb'), '\testFolder')).GetDescendant(Null,NULL);

INSERT INTO [dbo].FileTableTb  ([name],[file_stream],path_locator) SELECT 'test1.txt', CONVERT(VARBINARY(MAX),'TestFileText'), GetPathLocator(CONCAT(FileTableRootPath('FileTableTb'), '\testFolder')).GetDescendant(Null,NULL) AS FileData

Parent_Path_Locator column is readonly !

E) Read Files

with Explorer - get UNC Path of filetable:
SELECT FileTableRootPath('TestFileTable') AS FileTableRootPath


physical path of filetable isn't available, this UNC Path is given by a virtual device
The Filetable stores the files like filestream in a guid structure but offers a filesystemdriver, which respresents those files in a more readable form under a UNC Path, which is available from:
SELECT FileTableRootPath('TestFileTable') AS FileTableRootPath

select stream_id, name, convert(varchar(max), file_stream) as textContent, file_stream.GetFileNamespacePath() as RelPath,
FileTableRootPath('TestFileTable')+file_stream.GetFileNamespacePath() as AbsPath from TestFileTable

Sql Server Filestream using C#

1) WRITE

            using (TransactionScope transactionScope = new TransactionScope())
            {
             
                //1. create Record with Empty Blob (File)
                SqlConnection sqlConnection1 = new SqlConnection(conStr);
                sqlConnection1.Open();

                SqlCommand sqlCommand1 = sqlConnection1.CreateCommand();
                sqlCommand1.CommandText = @"DECLARE @Out TABLE (ID uniqueidentifier)
                                            Insert Into Blob2(Blob) output inserted.ID into @Out values(Cast('' As varbinary(Max)))
                                            Select BLOB.PathName() As Path From BLOB2 Where Id =(SELECT id FROM  @Out)";
                string filePath1 = (string) sqlCommand1.ExecuteScalar();

                //2. Get SqlFileStream to empty File createt in Step 1
                SqlConnection sqlConnection2 = new SqlConnection(conStr);
                sqlConnection2.Open();

                SqlCommand sqlCommand2 = sqlConnection2.CreateCommand();
                sqlCommand2.CommandText = "Select GET_FILESTREAM_TRANSACTION_CONTEXT() As TransactionContext ";
                byte[] transactionContext1 = (byte[]) sqlCommand2.ExecuteScalar();

                //3. Write Data into Stream and Close
                SqlFileStream sqlFileStream1 = new SqlFileStream(filePath1, transactionContext1, FileAccess.Write);
                byte[] fileData = Encoding.ASCII.GetBytes(nameof(AdoFileStreamTest)+" "+DateTime.Now);
                sqlFileStream1.Write(fileData, 0, fileData.Length);
                sqlFileStream1.Close();
                transactionScope.Complete();
            }

2) READ

            using (TransactionScope transactionScope2 = new TransactionScope())
            {

                SqlConnection sqlConnection3 = new SqlConnection(conStr);
                sqlConnection3.Open();

                //1. Get Path & Transaction Scope
                SqlCommand sqlCommand3 = sqlConnection3.CreateCommand();
                sqlCommand3.CommandText = @"Select Top 1 Blob.PathName() As Path,
                                            GET_FILESTREAM_TRANSACTION_CONTEXT() As TransactionContext
                                            From Blob2 Order by Created desc";
                
                SqlDataReader reader = sqlCommand3.ExecuteReader();
                reader.Read();
                string filePath = (string)reader["Path"];
                byte[] transactionContext2 = (byte[])reader["TransactionContext"];

                //2. read file
                SqlFileStream sqlFileStream2 = new SqlFileStream(filePath, transactionContext2, FileAccess.Read);
                byte[] data = new byte[sqlFileStream2.Length];
                sqlFileStream2.Read(data, 0, Convert.ToInt16(sqlFileStream2.Length));
                res = Encoding.ASCII.GetString(data);
                sqlFileStream2.Close();
            }

3) maybe need to config Distributet Transaction Manager:


down voteaccepted
To enable MSDTC on the business management server that is running on Windows Server 2008 click Start, Run, type dcomcnfg and then click OK to open Component Services.
In the console tree, click to expand Component Services, click to expand Computers, click to expand My Computer, and click to expand Distributed Transaction Coordinator.
Right click Local DTC, and click Properties to display the Local DTC Properties dialog box.
Switch to the Security tab.
In the Security Settings section, click Network DTC Access.
In the Client and Administration section, select Allow Remote Clients and Allow Remote Administration.
In the Transaction Manager Communication section, select Allow Inbound and Allow Outbound.
In the Transaction Manager Communication section, select Mutual Authentication Required (if all remote machines are running Windows Server 2003 SP1 or Windows XP SP2 or higher), select Incoming Caller Authentication Required (if running MSDTC in a cluster), or select No Authentication Required if some of the remote machines are pre-Windows Server 2003 SP1 or pre-Windows XP SP2. No Authentication Required is the recommended selection. Select Enable XA Transactions, and then click OK.

Monday, October 17, 2016

Entity Framework no InsertFunction element exists

because it has a DefiningQuery and no InsertFunction element exists in the ModificationFunctionMapping element


most likly: No primary key defined => EF treats Table as view and generates read only code

I had to remove the DefiningQuery Element in the .edmx File and also I removed the store: 
like described here:

Ef Entity Framework and Filestream


        public void WriteAndReadFileTest()
        {
            var _ctx = new testFileStreamEntities();

            //Write
            var sw = Stopwatch.StartNew();
            string writeString = "Hallo wie gehts ? "+DateTime.Now;
            var writeBlobRec = new BLOB2();
            writeBlobRec.BLOB = Encoding.ASCII.GetBytes(writeString);
            writeBlobRec.ID = Guid.NewGuid();
            _ctx.BLOB2.Add(writeBlobRec);
            _ctx.SaveChanges();
            sw.Stop();
            Debug.WriteLine($"Writing took {sw.ElapsedMilliseconds}ms");

            //Read
            sw.Restart();
            var blobRec = _ctx.BLOB2.FirstOrDefault(x => x.ID==writeBlobRec.ID);
            string readString = Encoding.ASCII.GetString(blobRec.BLOB);
            sw.Stop();
            Debug.WriteLine($"reading took {sw.ElapsedMilliseconds}ms for {readString}");

        }



Thursday, October 06, 2016

Mehr als eine RemoteDesktop Sitzung unter Windows 10 / more than one Remote Desktop (RDP) session on Windows 10



http://woshub.com/how-to-allow-multiple-rdp-sessions-in-windows-10/

buildnr = ver sion = Name Windows 10 Versionen ( Type ver in commandshell to get buildnr)
10.0.10240 = 1507 = first Windows 10 Version (Threshold1)
10.0.10586 = 1511 = November Update
10.0.14393 = 1607 = Aniversary Update

Wednesday, October 05, 2016

get all resources of an assembly

Assembly a = Assembly.GetExecutingAssembly();

string[] allManifestResourceNamess = a.GetManifestResourceNames();



foreach (string resourceName in allManifestResourceNamess)


{
Trace.WriteLine(resourceName);

if (resourceName.EndsWith(".sql")) //SQL script Files


{
using (TextReader tr = new StreamReader(a.GetManifestResourceStream(resourceName)))


{
string s = tr.ReadToEnd();


}
}
else if (resourceName.EndsWith(".resources")) //real resources with key Value pairs


{
using (ResourceReader reader = new ResourceReader(a.GetManifestResourceStream(resourceName)))


{
IDictionaryEnumerator dict = reader.GetEnumerator();
while (dict.MoveNext())


{
string key = dict.Key as string;
object val = dict.Value;

}
}
string manifest = resourceName.Replace(".resources", string.Empty);
ResourceManager rm = new ResourceManager(manifest, a);



ResourceSet resourceSet = rm.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)


{
string resourceKey = entry.Key.ToString();
object resource = entry.Value;


}
}
}

webserver iis install webdeploy


IIS Server

start net start wmsvc

download installer:
https://technet.microsoft.com/en-us/library/dd569059(v=ws.10).aspx

then search webDeploy 3.6 (right upper Corner search field)



net start wmsvc & net start msdepsvc
the Web Managment Service must be started, Port 8172 opened
check with telnet

check with browser:
https://52.174.50.95:8172/msDeploy.axd




To diagnose installation problems, Web Deploy MSI logs are placed under %programfiles%\IIS\Microsoft Web Deploy v3

https://www.iis.net/learn/publish/troubleshooting-web-deploy/troubleshooting-common-problems-with-web-deploy

add USer to IIS Managers !!! and on site level to iis Permissions

if username is wrong or ha sno rights, it could be that error 404 (not found) instead of 401 (no rights) is returned


Visual Studio 2015

Server: Ip Adress or name of server, no http etc
SiteName: Default Web Site/test
Username: localhost\admin
pwd...
DestUrl: http://serverNameOrIp/test

test app has to exist on the server

Tuesday, October 04, 2016

IIS Webserver Anwendungs/Application Pool Timeout

wenn die Website beim ersten Aufruf lange braucht um geladen zu werden, so kann man die AppPool/erweiterte Eigenschaften / Leerlauftimeout erhöhen, z.b 1440 Minuten = 24h (60*24),
schienbar sind 1700min (28,3h) max

if webapp Needs Long to start,, you can increase appPool/ext.properties/idleTimeout eg. 1440 minutes = 24 hours. it seems that 1700 (=28,3h) is maximum