Tuesday, November 15, 2011

Error: Delegate System.Func <> does not take 1 arguments

If you get the error
Delegate 'System.Func<entityName,int,bool>' does not take 1 arguments
or
Cannot convert lambda expression to type 'string' because it is not a delegate type

then check the linq query and confirm that the "where" condition has == instead of = ..
var allProducts = from p in context.Products where p.productID == 1 select p;

I wasted a lot of time on this and would like to help anyone else who might have similar issues

Friday, August 12, 2011

Add a table that was deleted in an Entity diagram

If you have come here, I understand your pain. You deleted a table from a entity diagram for some reason and you have trying in vain to add it back using the "update data model from database" option.

Unfortunately there is no easy way to add it back. For some reason, the people who designed it thought that if a user deleted a entity, why would he want to add it back again? But they forgot there are various reasons why someone would want to do it. For eg, I created a model from a database on server A. The database had a table nemed "Attendees". All the other tables started with a lower case. Now moved my database server to a new server and so I thought its a good time to rename this table for consistency. So I renamed and configured my entity model to refresh from the new server expecting that everything would be alright. But lo and behold, now I had 2 entities in the diagram called "Attendees" and "attendees1". Ok, I understand .. when the wizard could not find a table called "Attendees" instead of deleting the table, it thought it might be a entity I created manually and so left it as it is. When it now a new table with the same name, it just created another entity with "1" attached to the end.
I can solve this by just deleting both the enitities and refreshing the table again. Surprisingly, it was not so easy. When I deleted and refreshed, the "attendee" table would no longer appear. What I found is that it just deletes from the designer, but keeps a reference to the table.
Ok, again I understand the reason why the designer leaves the reference is because how else will the designer figure out other entities that I have actually deleted from the diagram, but still have same tables in the database? But I think they could have built that function in the wizard so the user can decide on what tables he would not like in the diagram and what tables he would like to add again.

Anyway, back to what this post is all about. How will I add this table back again? There are 2 options and both options involve editing the edmx file

     Option 1) Delete all reference to "attendees" entity in the diagram
     Option 2) Add the "attendees" reference to the places where it might be missing so the designer adds it back.

Option 1 would be tricky if you have lots of references for that table and the table design is complex.
In my case, I opted for option 2 because I thought adding a reference back to the designer would be easy for me.
Option 1 is pretty straight forward and so I will not discuss on how to go about doing it
For option 2, you will have to do the following....
There are 3 main sections in the edmx file
  1. Storage model - a refernce to all the tables
  2. Conceptual model - entities that are part of the entity model
  3. Mapping - entity properties to database column mapping
The missing table "attendees" was missing in the sections conceptual model and mappings.

Step 1: Add missing enity in conceptual model
Copy the attendees tag from Storage model
<EntitySet Name="attendees" EntityType="MyModel.Store.attendees" store:Type="Tables" Schema="dbo" />

into the tag within  "EntityContainer". Remember to make the changes like removing attributes not needed and also removing the ".store" from the namespace. For my case the tag I added would look like this
<edmx:ConceptualModels>
  <Schema Namespace="MyModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
   <EntityContainer Name="MyEntities">
      <EntitySet Name="attendees" EntityType="MyModel.attendees" />

Step 2: Add missing entity tag to conceptual model
Copy the attendees entity tag and its contents from storage model
<EntityType Name="attendees">
<Key>
  <PropertyRef Name="attendees_id" />
</Key>
    <Property Name="attendees_id" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="Column1" Type="bigint" Nullable="false" />
    <Property Name="Column2" Type="varchar" Nullable="false" />
    <Property Name="Column3" Type="bit" Nullable="false" />
    <Property Name="Column4" Type="dateime" Nullable="false" />
</EntityType>

as a new entity type under the ConceptualModel\Schema tag .. It will look something like this
<edmx:ConceptualModels>
<Schema Namespace="MyModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
   <EntityType Name="attendees">
    <Key>
      <PropertyRef Name="attendees_id" />
    </Key>
     <Property Name="attendees_id" Type="Int64" Nullable="false" />
     <Property Name="Column1" Type="Int64" Nullable="false" />
     <Property Name="Column2" Type="String" Nullable="false" />
     <Property Name="Column3" Type="Binary" Nullable="false" />
     <Property Name="Column4" Type="DateTime" Nullable="false" />
  </EntityType/>
Note, I made changes to the types of the columns .. for eg, all bigint are Int64, varchar as string, bit as binary. I also removed any other attributes that are not needed like StoreGeneratedPattern="Identity" from the primary key "attendees_id"

Step 3: Add the mapping
Add the mapping as below
<edmx:Mappings>
  <Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
      <EntityContainerMapping StorageEntityContainer="MyModelStoreContainer" CdmEntityContainer="MyEntities">
         <EntitySetMapping Name="attendees">
            <EntityTypeMapping TypeName="IsTypeOf(MyModel.attendees)">
               <MappingFragment StoreEntitySet="attendees">
                  <ScalarProperty Name="attendees_id" ColumnName="attendees_id" />
                  <ScalarProperty Name="Column1" ColumnName="Databasecolumn1" />
                  <ScalarProperty Name="Column2" ColumnName="Databasecolumn2" />
                  <ScalarProperty Name="Column3" ColumnName="Databasecolumn3" />
                  <ScalarProperty Name="Column4" ColumnName="Databasecolumn4" />
               </MappingFragment>
         </EntityTypeMapping>
       </EntitySetMapping>
For this change, note that you need to add a mapping for each column in your database

Step 4: Get all other relations for the table
Its quite possible that you had other relations for this with other database tables and that is the reason you opted for option1 instead of option2. For this you just need to open the designer again, right click and select the "Update model from database" option and Viola! all the other relations and mappings are automatically added ..
Hope this helps ..

Wednesday, April 6, 2011

Create PDF file from a template using Aspose.net

There are many applications where reports or custom documents have to be created in PDF formats. There are various tools available in the market to create PDF document on the fly. If you selected the tool provided by Aspose (http://www.aspose.com/community/files/default.aspx), read on ..

My requirement was to create a PDF document on the fly within a ASP.net application. The document to be created was a certificate and it had a fixed format. Only some of the text (like name, date) within the certificate had to fetched from the database and the document had to be created on user request (on demand, on the fly).

Instead of creating the whole document from scratch each time the document is to be created, I thought the best approach would be to create a PDF template and add form fields for all the fields that would change. Then use Aspose control to open the template, fill the fields. I thought this would be an efficient way to create these documents and response time would be reduced drastically. It would also be easier to code because most of the content of the document is in place and I do not have to code to place the content with the document.

As this was a ASP.net application and the document was to be created only the user requested for it (using a link within a web page), I did not want to save the document on the web server because I did not want to go through the hassle of having to delete these documents later or having piles of documents using my web server space. So the solution was to use streams and manage everything in memory.

The document also had to be secure and the user must not be able to edit the fields or make any changes to the document. The only permission that was to be available to the users was to open the document and print it. So here is the code I finally came up with



public static MemoryStream CreateCertificate(string pName, string pDate)
{
//open template
string lpdfTemplate = "

Hiding a node in a TreeView control

I had a web page with a treeView control and I wanted to hide a particular node for a specific condition. I thought this would be pretty easy and I might just have to set the "Visible" property of the node. But I was surprised to see that the node does not have this property maybe because the node is not a control.

If the treeview is built from a data source, you can use the TreeNodeDataBound event to acheive this. But its not as simple as doing
e.node.visible because as I said, visible is not a property

Even treeviewControl.Nodes.Remove(e.node) will not work if you are trying to remove a node that is a leaf node (node that does not have children).

So to remove a node, just try this code
e.Node.Parent.ChildNodes.Remove(e.Node);

Unable to resolve dimension value "match_parent" in attribute "layout_width"

Unable to resolve dimension value "match_parent" in attribute "layout_width"


If you get the above error while developing any Android application, just replace change "match_parent" with "fill_parent"

I spend some time figuring this out .. so thought maybe this would help someone out there who has similar issues