visit Epsilon Minded Gregory Mazarakis | issues

Entity Framework and many-to-many relations

by Gregory Mazarakis 22. April 2010 19:39

Yesterday I came across an issue in the Entity Framework that really frustrated me for a couple of hours. I decided to leave it in peace until I was able to think clearly again. Today I went back to tackle the issue and I was finally able to find a solution to my problem.

Issue

I have three tables in place, one describing a user account, one describing an in installation and finally on describing the relation between them. Both the UserAccount table and the Installation table have a primary key set on an identity column named after the table (UserAccountId and InstallationId). The identity column is set to increment with 1 step at the insert of a row. The UserAccountInstallation table provides the mapping between user accounts and installations:

image

no rocket science here… the issue now is that whenever I try to insert a new installation object into the database, I gracefully receive a System.Data.UpdateException exception, stating in the message:

A value shared across entities or associations is generated in more than one location. Check that mapping does not split an EntityKey to multiple server-generated columns.

Solution

It seems that Visual Studio 2010 RC causes the problem. When creating/refreshing an entity model in the visual studio IDE, the columns that are marked as identity columns in the database are given the attribute “StoreGeneratedPattern” with value “identity” in the mapping:

UserAccount 

<EntityType Name="UserAccount">
  <Key>
    <PropertyRef Name="UserAccountId" />
  </Key>
  <Property Name="UserAccountId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
  <Property Name="SyncServerId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
  <Property Name="Title" Type="nvarchar" MaxLength="8" />
  <Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="50" />
  <Property Name="MiddleName" Type="nvarchar" MaxLength="50" />
  <Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="50" />
  <Property Name="Suffix" Type="nvarchar" MaxLength="10" />
  <Property Name="Username" Type="nvarchar" Nullable="false" MaxLength="100" />
  <Property Name="CultureCode" Type="nvarchar" Nullable="false" MaxLength="5" />
  <Property Name="IsAdmin" Type="tinyint" Nullable="false" />
  <Property Name="NameStyle" Type="bit" Nullable="false" />
  <Property Name="EmailAddress" Type="nvarchar" MaxLength="50" />
  <Property Name="EmailPromotion" Type="tinyint" Nullable="false" />
  <Property Name="Phone" Type="nvarchar" MaxLength="25" />
  <Property Name="PasswordHash" Type="varchar" Nullable="false" MaxLength="128" />
  <Property Name="AccountNumber" Type="varchar" Nullable="false" MaxLength="10" StoreGeneratedPattern="Computed" />
  <Property Name="ModifiedDate" Type="datetime" Nullable="false" />
</EntityType>

Installation 

<EntityType Name="Installation">
  <Key>
    <PropertyRef Name="InstallationId" />
  </Key>
  <Property Type="Int32" Name="InstallationId" Nullable="false" a:StoreGeneratedPattern="Identity" xmlns:a="
http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
  <Property Type="String" Name="Identifier" Nullable="false" MaxLength="38" FixedLength="true" Unicode="false" />
  <Property Type="Byte" Name="IsActiveCode" Nullable="false" />
</EntityType>

UserAccountInstallation 

<EntityType Name="UserAccountInstallation">
  <Key>
    <PropertyRef Name="UserAccountId" />
    <PropertyRef Name="InstallationId" />
  </Key>
  <Property Name="UserAccountId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
  <Property Name="InstallationId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
</EntityType>

The issue is caused because the columns in the mapping table are also given the same attribute and value, resulting in the database trying to auto-increment a column that is not configured to do so! The solution is to dive into the XML representation of the entity model and remove the attribute from the properties where it is not applicable.

UserAccountInstallation 

<EntityType Name="UserAccountInstallation">
  <Key>
    <PropertyRef Name="UserAccountId" />
    <PropertyRef Name="InstallationId" />
  </Key>
  <Property Name="UserAccountId" Type="int" Nullable="false" />
  <Property Name="InstallationId" Type="int" Nullable="false" />
</EntityType>

Even further… my UserAccount table contains a reference to a another table that holds server configuration. This is a many-to-1 relationship as many user accounts can be member of the same server. The server is represented by its Id (auto-generated), in column SyncServerId… it seems that this column is also given the wrong attributes and I can fairly assume now that I will run again into the same issue when I try to include a new user account.

Is think the issue will be caused with every association created by the wizard where an endpoint is an identity column in a table.

In the mean time I found out that the problem is already brought to the attention of Microsoft: https://connect.microsoft.com/data/feedback/details/540058

Tags: , ,

Development | .net | issues

Collaboration Data... chaos! ...the continuum...

by Gregory Mazarakis 23. April 2009 02:03

It didn’t take much time to find out that approaching your Lotus Notes client using .NET technology can be done by using an interop assembly, name Interop.Domino.dll. After I found this piece of information I got so excited because there seemed to be a standardized way to approach the Lotus Notes client. And indeed, the assembly is filled with objects, interfaces, variables and methods that all reassemble around the functionality used within the client.

In a second stage into my research I thought I would “quickly” gather some documentation in regards to the interop assembly so I can understand the structure of the objects, the relation they have as also to locate the exact location of the data I need, to synchronize both collaboration platforms. It turned out that finding documentation on the interop assembly for the Domino directory is a challenge on its own. All I was able to find was maybe a dozen articles presenting some examples on how to use the assembly, but I failed to find even the smallest piece of information in regards to object structure, relations and contained data.

I did some reverse engineering by examining the assembly, assisted by useful information I found on www-12.lotus.com. The information provided here describes the properties and methods of an object, as also the hierarchy but its examples are limited to Lotus Notes Script. The syntax is similar to a Visual Basic syntax, but for iteration through collections they make use of commands that are not available in VB.NET. A bit of casting and converting will be necessary to get to the final data. As a result of this reverse engineering I think the following can be stated:

  • We have several physical files we need to access (I prefer to sync with local repository, instead of syncing with the server).
  • These files contain views; it is a matter of finding the correct one in order to synchronize contacts.
  • We have a Lotus Notes Session, which contains several databases represented by their physical names.
  • Both views and databases contain documents. Documents are the essence of the platform as they contain the actual information. The way they are presented on the screen seems to depend on which view they are outputted through.
  • Documents contain items; an item is an individual piece of data.
  • Off course I was able to gather much more information in regards to the assembly but I don’t think it is applicable to post it in this entry. It is to late... I need some sleep! If somebody needs additional information feel free to contact me... I will start building some prototypes now to see how I can reach the data.

    Tags: ,

    Development | issues

    Collaboration Data... chaos!

    by Gregory Mazarakis 21. April 2009 21:27

    Maintaining my personal data has always been a challenge to me, as organized as I might be, according to some people. Working in different environments also implies that there is a need for a central storage of data, accessible to any environment and without that environment being predefined. How can I achieve that? This is a question that has kept me busy many times in the past. Every day I am confronted with some kind of a hole in my collaboration data... wrong contact info, missing contacts, etc, etc.

    Keeping my documents and development in sync is something I succeeded to do pretty much from the beginning when the problem arose. I keep my files in sync between my laptop and my PC at home with the help of some tools that use the concept of "workspaces". On the other hand, as stated above, synchronizing my collaboration data (aka Contacts, Appointments, etc, etc) remains still a challenge. That challenge became even bigger when I started doing projects for a client of mine that makes use of the Lotus Notes application as their collaboration platform... I am lost... contacts in Lotus Notes, contacts in MS Outlook on my laptop, contacts in MS Outlook on my PC, contacts on my mobile phone...  everywhere I turn I have a different set of contacts! Imagine the chaos in my calendar!

    I decided to confront the issue. I will start building a tool to synchronize some collaboration data between the two platforms and I will make the code available when it is ready.

    Tags: ,

    Development | issues

    Powered by BlogEngine.NET 1.6.0.0
    Theme by Mads Kristensen

    Gregory Says...

    ..."Find something you love to do and you'll never have to work a day in your life"...

    Gregory Mazarakis

    me...

    Application/Solution Developer and Project Manager in a wide variety of business applications, driven by the need to obtain knowledge. Particularly interested in client/server applications, web applications and relational database design using MS-SQL Server or other products. Strong analytical and communication skills are pushing my career towards Project Management and a more abstract approach of the used technologies.

    Mother tongue is Greek and Greece was, is and will always be one of my top passions. Other languages used on a daily basis are Dutch and English...

    thank you for visiting!