Wednesday, September 24, 2014

VS: Automatically create a NuGet Package from project upon build

Here's a neat little approach I use to effortlessly build NuGet packages.

- Get NuGet.exe and put it in the project folder. I also add it to our source control.
- Create a new Build Target named "NuGet". (optional, see below)
- In the Post Build Events of the project you want to make a NuGet package from, enter this:
if $(ConfigurationName) == NuGet (
  "$(ProjectDir)nuget.exe" pack "$(ProjectDir)$(ProjectFileName)" -OutputDirectory "\\target\directory\NuGet Feed" -Prop Configuration=$(ConfigurationName)
)
To use it, you just select the NuGet target, and build the project. It'll build the package and put it in the OutputDirectory folder.

The new "NuGet" target is in fact optional and you could use "Release" in the Post Build Event condition.

Also, you might want to edit the project's Assembly Infos and set the Company, Name, and Description properties. Pay special attention to the Version property too. Those properties appear in the NuGet package manager.

For more information on NuGet and how to get it, check this out.
To learn how to make a NuGet feed, check this out. Especially the local one. It's as simple as making a new directory, and this is what I use.

Have fun!

UPDATE:
Here's a NuGet with more features to do just that:
https://www.nuget.org/packages/CreateNewNuGetPackageFromProjectAfterEachBuild/

Friday, August 22, 2014

Entity Framework 6 Code First: error 3023: Problem in mapping fragments starting at lines xxxx:Column has no default value and is not nullable. A column value is required to store entity data

There are many reasons why this error would happen. There's a known bug in 6.1 which will be fixed in 6.2. But my problem wasn't related to it. Here's what happened for me.

I use a single table, tbl_Person,  to map a hierarchy, like this example, where Person is abstract :

And I use this mapping using Fluent API:

modelBuilder.Entity<Person>()
 .ToTable("tbl_Person")
 .HasKey(m => m.PersonID)
 .Map<Student =>(m.Requires (discrimination stuff) )
 .Map<Instructor>(m => m.Requires (discrimination stuff) )

And then later, I added another kind of Person to my model. Let's say a "Director"  but I forgot to add the mapping. That got me the error whenever I would try to use a DbContext. So I just added the mapping for "Director" and the error went away.

By the way, a discriminator column can be NOT NULL and have no default value, as opposed to what the error lead me to think.

Coffee time!

Tuesday, August 19, 2014

Entity Framework Code First: map to updatable view with INSTEAD OF INSERT trigger

At first, I was glad we could map entities to SQL views. Just map them to a view instead of a table. But when we need to update or delete, we need an updatable view. This is doable as explained here. My view was a join of multiple tables so I had to rely on an INSTEAD OF triggers. This works fine in theory or if you do your own queries. However, Entity Framework (v6 in my case) doesn't like them very much and I get this error when I add a new entity:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

Here' why it thinks no rows were affected. Using SQL Server Profiler, I've been able to catch the following query that EF generates when I call SaveChanges() on my DbContext:

exec sp_executesql 
N'INSERT [dbo].[vw_ErpAndType]([Description], [ConnectionString], ...)
VALUES (@0, NULL, ...)
SELECT [idERP]
FROM [dbo].[vw_ErpAndType]
WHERE @@ROWCOUNT > 0 AND [idERP] = scope_identity()'
,N'@0 nvarchar(max) ,@1 bit, ...'
,@0=N'bill',@1=0 ...

See that part in bold and underlined red? This is how EF gets the key of the newly inserted row and give it back to the business object. The problem is that when there's an INSTEAD OF INSERT trigger, that scope_identity() instruction returns NULL because the trigger happens in another scope. So even if the insertion is successful, the query returns nothing and thus, EF thinks nothing happened and throws the error.

The workaround would be for EF to use @@identity instead but I don't believe we can do that.

This is as far as I went trying to use updatable views with EF. Now I'll see what can be done with mapped stored procedures for insert-delete-update.

Tuesday, July 1, 2014

Zebra EPL - Truncate text field

Zebra ZPL has this neat TB command which limits the field bounds. EPL doesn't seem to have this kind of feature. Here's how I've been able to do this. Place all the text fields in a form and use a variable with a maximum length:
V00,35,L,"" 
A600,30,1,4,6,2,N,V00 
A310,850,1,c,2,2,N,"ACCEPTED" 
?
1234567890123456789012345678901234567890
The result is:
1234567890123456789012345
ACCEPTED


Tuesday, May 20, 2014

DevExpress GridView CustomUnboundColumnData, e.Column always refers to same column

This just happened to me and the solution is very easy. I just didn't check for a solution at the right place. This will happen if your unbound columns all share the same FieldName, so make sure they are unique across the GridView.

Thursday, April 10, 2014

Devexpress WPF how to make Buttons

In case you were wondering where ordinary buttons went in devexpress for WPF, here is an example of how to make one.

First, make sure to set the dxe namespace:

xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" 

then:

<dxe:ButtonEdit Height="23" Margin="195,137,0,0" Width="75" ShowText="False" AllowDefaultButton="False">
 <dxe:ButtonInfo Content="Cancel" Click="btnBack_Click" />
</dxe:ButtonEdit>

Wednesday, April 2, 2014

Devexpress WPF Gridview: set row cell font size

Quite simple, even though I couldn't find anything on that matter. Here's a complete example, giving you can locate the automatically created TableView element in your XAML:

<dxg:TableView Name="tableView1" 
   ShowGroupPanel="False" 
   NavigationStyle="Row" >
 <dxg:TableView.CellStyle>
  <Style>
   <Setter Property="TextElement.FontSize" Value="8" />
  </Style>
 </dxg:TableView.CellStyle>
</dxg:TableView>