Type provider: How to regenerate? - f#

How would you make the LINQ-TO-SQL type provider, generate or/and regenerate the classes?
I've just added a new table to my database, and the type provider can't figure that out. I've tried to delete the line with the type provider, and type it once more - no luck. I've also tried to do a rebuild.. still no luck.
Edit:
I've defined the type provider like:
[<Generate>]
type dbSchema = SqlDataConnection<"conString">
and using it like:
let ctx = dbSchema.GetDataContext()

You're right - this seems to be quite tricky. I'm using SqlDataConnection type provider in a script file and the only way to update the schema that I've found so far is to make some minor (irrelevant) change in the connection string. For example, add space after = of one of the parameters:
[<Generate>]
type Northwind = TypeProviders.SqlDataConnection
<"data source=.\\sqlexpress;initial catalog=Northwind;integrated security=True">
[<Generate>]
type Northwind = TypeProviders.SqlDataConnection
<"data source=.\\sqlexpress;initial catalog=Northwind;integrated security= True">
// ^ here
The schema seems to be cached using connection string as the key, so if you change it back, you get the old schema again. I guess this is probably a bug, so adding whitespace is a possible workaround.
There is also a parameter ForceUpdate, but that doesn't seem to have any effect and the documentation doesn't say much about it.

Related

How to be able to use System Entity, in fulfillment, in Dialogflow?

I am getting undefined, when using agent.parameters.geo-country while using the System entity #Sys.geo-country.
This is the error I am getting.
https://drive.google.com/file/d/1-rP9rkvOB3Wm0KyGn846iFbMBFb2Iu9c/view?usp=drivesdk
JSON property syntax (x.y.z) doesn't like the dash. In order to get around that, you can use the alternative bracket syntax (x['y']['z'])
In your case, you could use agent.parameter['geo-country'].
Another thing you can do instead is look at the name of the paramter, and change it if you want.
For example, in the case below, the entity type is #sys.any, but I've named it to search. This means I could instead use agent.parameter.search which may be more useful to me.

Error inserting data with EF6 and Always encrypted

We are experiencing some issues with EF6 and Always encrypted feature.
I believe we need to set up something into DBContext, in order to instruct how to encrypt or decrypt columns, but I couldn't find a way to do this.
We already have an ADO access layer, and it works perfectly with encrypted fields. We would rather use EF instead of ADO.
Symptoms are:
With EF, We are able to query the data. And decryption process works fine.
Insertion process throws error below:
Operand type clash: varchar is incompatible with varchar(8000) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'Development_v2_qa') collation_name = 'SQL_Latin1_General_CP1_CI_AS'**
Query with where clause, using an encrypted field, throws same error.
Technologies used:
EF6 with Poco entities.
AzureKeyVault for storing encryp/decryp masterkey.
Using SSL Certidicate to authenticate against KeyVault
Connection string contains "Column Encryption Setting=enabled;"
AzureSqlServer
FWK4.6
ADO
We have some code which works fine with ADO. It works fine with every SqlConnection
// Instantiate our custom AKV column master key provider.
// It uses the GetToken function as the callback function to authenticate to AKV
SqlColumnEncryptionAzureKeyVaultProvider akvprov = new SqlColumnEncryptionAzureKeyVaultProvider();
akvprov.KeyVaultClient = SecureConfigurationManager.KeyVaultClient;
// Register the instance of custom provider to SqlConnection
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers = new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
// "SqlColumnEncryptionAzureKeyVaultProvider.ProviderName" is the name of the provider. It must match the string we used when we created the column master key
providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvprov);
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
Yep, I just found the same problem, needed to add
[Column(TypeName = "varchar(max)")]
in the POCO type before the field for it to work.
Be nice if the error was a bit clearer (and nicer still if NVARCHAR did actually work)
I'm working through the same issue. The problem is with the datatype mapping from C# to the database. Not all the lengths matter at all for always encrypted and varchars with Entity Framework, only varchar(max) or varchar(8000). I have all the entity framework working with azure key vault for all the datatypes, same as you. This link below shows how to do the insert with inline SQL. I've only worked with entity framework and hope I never have to work in inline sql, even though I might have to, if I can't find a way to shrink down the database storage overhead needed for encryption, or look to something like Stretch Db, also another feature in SQL Server 2016. Thanks Jakub Szymaszek and Microsoft.
I have conceded and made all of my data types varchar(max) and it works just fine. So string = varchar(max). The weird thing is that there is not 8000 characters in the encryption, but there is probably 8000 allocated.
"something1" becomes this after encryption and insert:
0x0190F9D80C3F70890FB154F2123459506AD5BDA165333710D161ED80E42FCAFA882C66FF5B68E412B5F9EE11A9F308201D0AE2BD4032151398171FDBE2F3AEA20D
Interesting thing about varchar(max) is that supposidly there is a link to a table or somewhere else the data is stored, beside the table it is inserted into, so varchar(max) may only take the amount shown. (I'm a dev)
The dataType for my column and stored procedure variables:
[testVarChar] varchar COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
The data type of the parameter targeting the SSN column is set to an ANSI (non-Unicode) string, which maps to the char/varchar SQL Server data type. If the type of the parameter was set to a Unicode string (String), which maps to nchar/nvarchar, the query would fail, as Always Encrypted does not support conversions from encrypted nchar/nvarchar values to encrypted char/varchar values. See SQL Server Data Type Mappings for information about the data type mappings.
https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/develop-using-always-encrypted-with-net-framework-data-provider

SqlEntityConnection configured with a local schema file

I want to use the SqlEntityConnection type provider in f# to query and update a db.
It works well when I use it with the connection string pointing to a live SQL Server DataBase.
type EntityConnection = SqlEntityConnection<"Data Source=myServer;Initial Catalog=myDb;...", Pluralize=true>
Now I want to get rid of the dependency with the live DB and, instead, use a local schema file. Given what I read on msdn, I gave a try to the following line:
type private EntityConnection = SqlEntityConnection<LocalSchemaFile="mySchemaFile.ssdl", Pluralize=true>
Unfortunately, it doesn't compile and the compiler's message is:
Error 46 The type provider 'Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders' reported an error: When using this provider you must specify either a connection string or a connection string name. To specify a connection string, use SqlEntityConnection<"...connection string...">.
So what should I do? If I leave the connection string, I have the feeling that I don't really turn off the dependency to the DB. For instance, if I try to switch the Data Source with a non-existing server, it doesn't compile.
You can provide a connection string name, along with a connection string in the configuration file.
You can still provide a localschemafile that will be used to cache locally the schema.
If you put the schema file under source control, the connection string will only be used as a default when calling GetDataContext() without parameter, but not when building or editing code.
You also need to set the parameter ForceUpdate to False.

Passing user name and password parameters to the type provider

I have created a type provider to a service that requires authentication by user name and password. The signature for creating the typed instance is something like this:
let tbl = new DemoTable<TableId="demo",User="user",Password="password">()
It all works just fine, the only problem is that I want to demonstrate this code, so I'd like the user name and password to come from some other source - a configuration file, another F# module (good approach when using scripting), etc.
What are my options for passing these parameters so they are not exposed in the course of demonstration?
One simple way is to use literals in a file that you don't show:
module MyInfo =
[<Literal>]
let user = "user name here"
[<Literal>]
let pwd = "password here"
And then in the file that you do show:
let tbl = new DemoTable<TableId="demo",User=MyInfo.user,Password=MyInfo.pwd>()
Specifying the user name and password directly as static parameters is certainly useful in interactive scripting scenarios. But as you say, sometimes it is also useful to keep those in a separate configuration file. F# does not come with any library that would make this easier, but you can implement the same pattern as, for example, the SqlDataConnection type provider which provides both options (see MSDN docs).
You can either specify the whole connection string:
type DB = SqlDataConnection<ConnectionString="Source=.; User=me; Password=mysecret">
or can either specify local config file and key name:
type DB = SqlDataConnection<ConnectionStringName="LocalDb", ConfigFile="App.config">
This is something that you'd have to implement in your type provider, but it seems like the best way to support both scenarios.
Change password on database (or make temporary user)->compile project->rechange password (or delete user).

BizTalk 2010: Access Context In Map

This could be a very basic question, but hopefully someone will be able to answer it.
I am receiving messages (HL7) using a custom receive pipeline. Inside my custom pipeline, I am promoting properties into the context. I have set up a map where I need to access these properties. However, I would like to access these properties on the send side. The reason why it needs to be on the send side is because I am attaching my map to the send port, so I assume that the message will have already hit the MessageBox and will be mapped on the send side. Hopefully that makes sense...
I know that there are a few 3rd party tools I can use, but I was hoping that there's a simple functoid, or some code I can enter in a scripting functoid that will access the context for me.
Would someone be able to point me in the right direction with this?
There is, indeed a C# functoid that allows access to context properties but it seems to only work with maps on a Receive Port or inside an Orchestration.
You can use the Context Accessor Functiod to do this... Combine it's pipeline component with yours and it should work... Beware it should be handled within the same thread...
http://contextaccessor.codeplex.com/
I don't know if this is possible. However, I had a similar requirement to access message context properties and I was able to populate a message with the context properties in an orchestration thanks to
Greg.Forsythe's excellent instructions
I had a similar situation to access the context properties to get the filename property in the my map. I did the below steps without using any external functoids. Hope this helps someone
Steps:
create a new schema say "FileSchema"
FileNode(rootNode)
-FileName (fieldElement)
Click the schema and in the properties target namespace - clear the namespace.
make the FileName property distinguished. Rt.Click FileName and show promotions and add FileName to Distinguished property tab.
In your target schema, add the field FileName. for me I added it to a SQL schema, since I need the filename for every row in the database
In your orchestration, use the message assignment shape and type the below
// create a variable varFileXML of type System.XML.XMLDocument
// I'm creating a xml same like the file schema and loading that to the XML variable and then assigning that to the Message of type FileSchema
varFileXML = new System.Xml.XmlDocument();
varFileXML.LoadXml("<FileNode><FileName>FileName_0</FileName></FileNode>");
Msg_FileSchema = varFileXML;
//Get the FileName to a variable of string type
varFileName = Msg_FlatFileSchema(FILE.ReceivedFileName);
varFileName = System.IO.Path.GetFileName(varFileName);
//Access the filename property from the message and assign the variable to that
Msg_File.FileName = varFileName;
Now that we got the FileName in to the message you can use that in mapping to your target schema
I used a transform shape to create a new inline map with source as your target schema and fileschema together and the destination as the target schema.I mapped the filename from the fileschema to my target schema the filename property
this is one of the many ways to get the context property. Hope it helps
thanks & regards
Silam

Resources