Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doesn't always recreate types on changed SQL source when using SqlFile #335

Closed
cmeeren opened this issue Apr 12, 2019 · 18 comments
Closed
Assignees

Comments

@cmeeren
Copy link
Contributor

cmeeren commented Apr 12, 2019

I have several times experienced SqlClient/SqlFile not updating generated types when source SQL files change. This is annoying in the IDE (where this behavior is fairly consistent), but is worse when a solution build does not generate types for the current SQL files, but instead for old SQL files.

Just now, I even experienced bugs in production (published through VS, with a different build config) due to SqlClient not picking up the file changes (even when the solution config changed).

This seems like a fairly serious issue (provided it actually is a bug with SqlClient).

I have no minimal repro because this doesn't happen all the time.

A re-build always fixes the problem. But for obvious reasons I don't want to have to remember to always manually re-build before publishing.

In case it's relevant, I use SqlClient like this:

use cmd =
  new SqlCommandProvider<
    const(SqlFile<"""SQL\searchOrders.sql""">.Text),
    ConnectionStrings.dbCompileTime>
    (ConnectionStrings.dbRuntime)
@cmeeren cmeeren changed the title Doesn't always recompile on changes Doesn't always recreate types on changed SQL source when using SqlFile Apr 12, 2019
@smoothdeveloper
Copy link
Collaborator

I don't think there is an easy way around from the TP standpoint and I agree it is annoying.

My current approach is to have the file containing the provider instanciations be generated by a script, that script will regenerate this file if content of .sql has changed or the file is out of date.

It also allows me to embed some metadata in my .sql files that has an impact on how the generated F# code looks like.

Another potential workaround is to have the .sql file be part of your project in some degree, so msbuild would decide to recompile since a file has been touched since last valid compile. I have not explored this.

Another one would be a watch tool that would touch F# files as soon as a .sql file referenced in SqlFile is touched but this doesn't feel like trivial effort.

I'd rather keep the compilation model behave the same, people get the same issue with editing files pointed in .resx files for example, only a clean or rebuild address this.

If there are ideas how this could be implemented, I'm eager to learn about them.

@cmeeren
Copy link
Contributor Author

cmeeren commented Apr 12, 2019

Thanks for the reply. Unfortunately, complicating our process with external tools is not a viable solution for us.

Another potential workaround is to have the .sql file be part of your project in some degree, so msbuild would decide to recompile since a file has been touched since last valid compile. I have not explored this.

They are indeed part of the project (primarily for easy access from VS). I don't know how to tell MSBuild to recompile, though. I figured it was supposed to happen automatically. Do you have any pointers?

@cmeeren
Copy link
Contributor Author

cmeeren commented Apr 12, 2019

Regardless of MSBuild though: When using SqlFile, I would expect it to pick up on file changes automatically, making the changes immediately visible. Is this unrealistic? Don't type providers normally work that way?

@smoothdeveloper
Copy link
Collaborator

Is this unrealistic?

no, but it is optimistic and I guess requires a lots of gaps to be bridged.

I don't have deep enough knowledge about type provider infrastructure if this is the place changes would need to happen.

Unfortunately, complicating our process with external tools is not a viable solution for us.

If you are able to figure a better workflow please share it.

I believe looking more into msbuild and how it tracks project resources is the best short term and integrated solution in your context and could be part of recommendations in the documentaiton.

@cmeeren
Copy link
Contributor Author

cmeeren commented Apr 12, 2019

Thanks! Yes, I agree that the documentation should be updated with a warning about forcing rebuild to make absolutely sure, and if possible also recommendations about using MSBuild to automatically rebuild when SQL files have changed.

@smoothdeveloper
Copy link
Collaborator

smoothdeveloper commented Apr 14, 2019

@cmeeren, @oikku's PR #332 got merged, could you give a try pulling and building master.

The workaround with this fix is to just edit your .fs / .fsx having the SqlFile defined after updating the pointed .sql file, it should then refresh in the IDE.

Can you confirm it helps you with this issue?

@smoothdeveloper smoothdeveloper self-assigned this Apr 14, 2019
@cmeeren
Copy link
Contributor Author

cmeeren commented Apr 15, 2019

Tried building master using build.cmd and referencing the compiled DLL in a new class library, but I'm only getting weird errors, such as (yes, the below is a single line in my output window)

C:\GH\FSharp.Data.SqlClient\ClassLibrary1\Library.fs(5,12): error FS3021: Unexpected exception from provided type 'FSharp.Data.SqlCommandProvider,CommandText="SELECT 1",ConnectionStringOrName="Data Source=localhost\SQLEXPRESS;Trusted_Connection=Yes;"' member 'GetMethods': The type provider 'FSharp.Data.SqlCommandProvider' reported an error: The design-time type 'System.Data.SqlClient.SqlConnection' utilized by a type provider was not found in the target reference assembly set '[tgt assembly FSharp.Data.SqlClient, Version=1.0.0.0, Culture=neutral;� tgt assembly netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51;� tgt assembly FSharp.Core, Version=4.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly Microsoft.Win32.Primitives, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.AppContext, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Collections.Concurrent, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Collections, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Collections.NonGeneric, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Collections.Specialized, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.ComponentModel.Composition, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.ComponentModel, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.ComponentModel.EventBasedAsync, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.ComponentModel.Primitives, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.ComponentModel.TypeConverter, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Console, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.Data.Common, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.Diagnostics.Contracts, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Diagnostics.Debug, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Diagnostics.FileVersionInfo, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Diagnostics.Process, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Diagnostics.StackTrace, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Diagnostics.TextWriterTraceListener, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Diagnostics.Tools, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Diagnostics.TraceSource, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Diagnostics.Tracing, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Drawing.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Dynamic.Runtime, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Globalization.Calendars, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Globalization, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Globalization.Extensions, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.Compression, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.IO.Compression.ZipFile, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.IO, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.FileSystem, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.FileSystem.DriveInfo, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.FileSystem.Primitives, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.FileSystem.Watcher, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.IsolatedStorage, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.MemoryMappedFiles, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.Pipes, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.IO.UnmanagedMemoryStream, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Linq, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Linq.Expressions, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Linq.Parallel, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Linq.Queryable, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.Http, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.NameResolution, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.NetworkInformation, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.Ping, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.Primitives, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.Requests, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.Security, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.Sockets, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.WebHeaderCollection, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.WebSockets.Client, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Net.WebSockets, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.ObjectModel, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Reflection, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Reflection.Extensions, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Reflection.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Resources.Reader, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Resources.ResourceManager, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Resources.Writer, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.CompilerServices.VisualC, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.Extensions, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.Handles, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.InteropServices, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.InteropServices.RuntimeInformation, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.Numerics, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;� tgt assembly System.Runtime.Serialization.Formatters, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.Serialization.Json, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.Serialization.Primitives, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Runtime.Serialization.Xml, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Security.Claims, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Security.Cryptography.Algorithms, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Security.Cryptography.Csp, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Security.Cryptography.Encoding, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Security.Cryptography.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Security.Cryptography.X509Certificates, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Security.Principal, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Security.SecureString, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.ServiceModel.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35;� tgt assembly System.Text.Encoding, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Text.Encoding.Extensions, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Text.RegularExpressions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Threading, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Threading.Overlapped, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Threading.Tasks, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Threading.Tasks.Parallel, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� tgt assembly System.Threading.Thread, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;� ...]'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using.

The code that produces this is

module Foo

open FSharp.Data

type Foo = 
  SqlCommandProvider<
    const(SqlFile<"""Test.sql""">.Text),
    @"Data Source=localhost\SQLEXPRESS;Trusted_Connection=Yes;">

@smoothdeveloper
Copy link
Collaborator

@cmeeren could you give some precision about the IDE / dotnet sdk version that are involved in your case?

I've been checking the changes in VS2019, but the error looks like this is running on netstandard or something like that.

Right now, the design time doesn't support netstandard, this is tracked in issue @matthid just opened: #337.

For now, either mono or netframework are needed for the design time / IDE, despite code compiled against the provider can ship / deploy on netstandard.

@cmeeren
Copy link
Contributor Author

cmeeren commented Apr 16, 2019

Yes, this was a .NET Standard library. I'll try again using the full framework.

@cmeeren
Copy link
Contributor Author

cmeeren commented Apr 16, 2019

I can confirm that the changes work as you describe: Any edit to the .fs file (even without saving) will seemingly invalidate the VS cache. This makes it easier to trigger the update in the IDE, which I appreciate.

However, I just want to be clear that this is not really a workaround or fix for this particular issue. This issue centers on the build experience, not the IDE experience (sorry if that wasn't clear). It is still the case that if a project is built, and then an SQL file edited, a new build (normal build, not rebuild) will still skip the project because VS believes it is already built and up-to-date. This happens even if you make an edit and then undo it, regenerating the types in the IDE; the IDE may then say that the SQL is invalid, but since no files have changed, the project is still skipped when building. Conversely, if you simply re-save the .fs file without modifying it, the IDE does not update, but the project is re-built and errors picked up there.

For this issue to be considered fixed, any edit to the SQL file must cause a re-compilation (and preferably also a refresh in the IDE). We can't and shouldn't depend on devs remembering to make a change to relevant .fs files whenever SQL files have been modified.

Again, though, I appreciate the simplicity of refreshing VS - it was a pain to re-load the project, and that particular issue is now at least remedied, if not fixed.

As for a potential solution: Would it be possible to use FileSystemWatcher for this?

@cmeeren
Copy link
Contributor Author

cmeeren commented Apr 16, 2019

Top result for "type provider watch file"; might be relevant:

The FileSystem type provider

This tutorial shows the use of the file system type provider. It allows to browse your file system via Intellisense and provides compile time checks for directories and files. The FileSystem type provider invalidates itself whenever any child dirs/files changed in any way.

(emphasis mine)

@oikku
Copy link

oikku commented Apr 17, 2019

For this issue to be considered fixed, any edit to the SQL file must cause a re-compilation (and preferably also a refresh in the IDE). We can't and shouldn't depend on devs remembering to make a change to relevant .fs files whenever SQL files have been modified.

I noticed the same problem but that it is only problem in development phase for myself. Release will always be the full rebuild. If someone can propose some way to find out what fs files should be recompiled when sql file is changed then I'm more than happy to try to fix that problem also.

Another option I was thinking is that is it possible that this recompile problem would go away if these SqlFile types would generative types instead of erased types. I'm not too familiar with type providers but if I understood the difference right then these generative types would be in own assembly and when that is changed then VS should be able to understand that it should recompile files that depend on types in that assembly.

@smoothdeveloper
Copy link
Collaborator

Another option I was thinking is that is it possible that this recompile problem would go away if these SqlFile types would generative types instead of erased types. I'm not too familiar with type providers but if I understood the difference right then these generative types would be in own assembly and when that is changed then VS should be able to understand that it should recompile files that depend on types in that assembly.

Doing the change for the library to be 100% generative is not a small task, I'm not familiar enough with quotation stuff happening beside observations on compiled code and adjusting some of those quotations.

If we could compile those to IL it could remove one barrier, SqlEnumProvider is the only which is currently generative.

I still don't think this would solve the matter of pressing f5 after saving a .sql, what is needed is a couple of msbuild guidelines in the documentation requiring to add the .sql files to the project in some fashion so they get added as a dependency to rebuild the assembly.

Involving the compiler, the TP SDK and/or type provider implementation feels much more complicated to me.

Few guidelines for end users:

  • For rapid iteration after saving .sql, FSI usage is probably the easiest, by reevaluating the type definitions and the code retrieving the data
  • To make sure the .sql is embeded in places it is used, use a full build script / CI, it is anyways needed if you want to deliver the software
  • If the situation is in between, use a .fsx to update (if needed) the commands instanciation in a generated file or adjust your build/project files so they pick up changes to .sql files and issue a rebuild

@cmeeren
Copy link
Contributor Author

cmeeren commented Apr 30, 2019

To make sure the .sql is embeded in places it is used, use a full build script / CI, it is anyways needed if you want to deliver the software

It is certainly best practice. But unfortunately many "older" companies are caught in a quagmire of legacy systems where MSDeploy, aka "Right click project in VS and click Publish" - or heck, even "Build project in Release mode and copy to deploy" - is the standard (and perhaps currently the only viable) method of deployment, with a giant mono-repo, no CI/CD pipelines set up and no resources (or expertise, for that matter) to prioritize it.

(If it sounds like I'm speaking out of personal experience, that's no coincidence. ;) )

@cmeeren
Copy link
Contributor Author

cmeeren commented May 3, 2019

Hmm, strange. I found a project setting that I thought would help:

<UpToDateCheckInput Include="**\*.sql" />

What happens is that the project is seemingly re-built (if I interpret the VS output window correctly) if the SQL files are edited, but unless any F# source files are edited too, the TP does not pick up any changes.

I tested this by compiling a project, editing an SQL file to be invalid, and then compiling the project again. The project compiles successfully (which it shouldn't), whereas if I edit an F# source file too, compilation fails due to a TP error (correct behaviour).

(This was tested using the currently released SqlClient, but I don't think that matters much, because the workaround posted previously in this thread still requires an F# source file edit and just impacts the IDE experience, not the build experience.)

@cmeeren
Copy link
Contributor Author

cmeeren commented May 13, 2019

Will #332 be released soon? Would be great to have it. :)

@cmeeren
Copy link
Contributor Author

cmeeren commented Sep 30, 2019

A workaround for the problem in my previous comment is to place the following in the project file (in addition to the UpToDateCheckInput:

<Target Name="TouchProjectFileIfSqlChanged" BeforeTargets="BeforeBuild" Inputs="**\*.sql" Outputs="$(MSBuildProjectFile)">
  <Message Text="SQL files changed. Changing project file modification time to force recompilation." Importance="High" />
  <Exec Command="PowerShell -NoProfile -ExecutionPolicy Bypass -Command &quot;(dir $(MSBuildProjectFile)).LastWriteTime = Get-Date&quot;" />
</Target>

This is part of #357.

@smoothdeveloper
Copy link
Collaborator

The tooling has changed since then, and there seems to be more agressive caching in Visual Studio at least.

The original issue was solved via #342

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants