Feeds:
Posts
Comments

Murphy’s Law: if anything can go wrong, it will. If BizTalk orchestration instance in a production server does not behavior as you expect it, how do you diagnose the problem? Remember, attaching debugger to an orchestration instance is usually impossible in this case.

DebugView is one of my favorite tools for troubleshooting issues in production environment. For many years, I have used it to debug Visual C++, Visual Basic, C#, ASP and ASP.Net web applications. No exceptions, I use it for BizTalk orchestration debug too. The System.Diagnostics.Trace.WriteLine method can be used to output string. Under the hood, it will call Win 32 OutputDebugString method. If DebugView is not enabled, there is no performance penalty. However, this method will hurt performance if you launch DebugView. In case you don’t have this tool, you can download free one here.

Alternatively, the System.Diagnostics.EventLog.WriteEntry method is extremely useful to log trace information. For example, you can insert an Expression shape into your orchestration, then specify Expression.

System.Diagnostics.EventLog.WriteEntry(“My BizTalk Application”, “Call Orchestration”, System.Diagnostics.EventLogEntryType.Warning, 9900);

Some business applications might require precisely control what should be logged at certain level and where to store log data. Instead of reinventing wheel, the Enterprise Library could be used to provide some extra features.

Above two methods are valid and useful but they require you plan ahead by writing trace code. What if you didn’t do that in your BizTalk orchestration, can you still collect trace data? Absolutely, In this case, you can try to enable process and message tracking using BizTalk Administration Console by checking Track Events/Message Bodies/Message Properties. However this is not a best practice recommended by Microsoft due to the performance consideration. Under the hood, BizTalk will copy the content of message to the BizTalk Tracking database during the orchestration execution even if you only need to exam one element. In the next BizTalk release, the BizTalk tracking feature is very likely replaced by BAM. If your organization plans to implement BAM, BAM could provide data for process tracking too. Although BAM is a powerful tracking engine since it’s fast and highly scalable, the drawback of BAM is BAM tools are awkward to use.

As a general rule, I try to avoid any solutions which have performance impact. For instance, some developers add a Send shape in Orchestration to write XML message to a send port just for diagnosis purpose. This is inacceptable because each Send shape in Orchestration will cause an orchestration instance to be persisted to database, which will noticeably slow down orchestration execution.

Personally, I think writing information to system Event Log is a better approach. It allows you easily diagnose execution sequence and information through Event Viewer. The performance impact is negligible. If you develop custom pipeline, custom functoid or .Net class library, you can use the same mechanism to log information. If you have multiple BizTalk servers, you can also takes advantage of MOM ( Microsoft Operations Manager ) or other system management tools such as Argent Guardian to monitor multiple servers. Often, combining two or more tracing methods will provide enough trace information and make it easier and quicker to resolve production issues.

 As I discussed in my previous blog, manually deploying BizTalk application is error-prone. For every BizTalk application, developing a script to automate deployment process is absolutely necessary. One of recent projects I’m working on requires to import and deploy policies with multiple rulesets and vocabularies. BTSTask , a command line tool from Microsoft, can be used to accomplish this task. For example

BTSTask ImportApp /Package:”C:\MSI Files\MyApplication.msi” /Environment:Test /ApplicationName:MyApplication /Overwrite

 
 

For detail steps about how to use BTSTask to import policy, click here.

 
 

Although BTSTask works, it demands policies are stored in an MSI file. This is not desirable because it’s not easy to compare different versions in binary format. Ideally, I would like to import an XML file. Luckily Microsoft provides a sample console application, which almost can fulfill my requirement. You can download the tool ( ImportExportRuleStore.exe ). Please note, you need to compile it using Visual Studio.Net 2005.

 
 

With this tool I can import XML policy file. Here is detail usage information by entering “ImportExportRuleStore.exe /?”

 
 

Usage:

     -import <filename>

     -export <filename> [ -rulesets <rulesets> | -vocabulary <vocabularies> ]

Additional options:

     -server <server>

     -database <database>

     -addreferencedvocabularies

 
 

<rulesets> are specified as <policyname>:<majorversion>.<minorversion>

<vocabularies> are specified as <vocabularyname>:<majorversion>.<minorversion>

If version is not specified, all versions of the policy/vocabulary are exported

 
 

Only the first letter of each option is necessary.

 
 

Examples:

     ImportExportRuleStore -import sample.xml

     ImportExportRuleStore -i sample.xml -s (local) -d BizTalkRuleEngineDb

     ImportExportRuleStore -export sample.xml -rulesets Policy1 Policy2:1.0

     ImportExportRuleStore -e sample.xml -r Policy1:3.5 -v MyVocabulary:1.0

 
 

Unfortunately, there is a minor glitch. It doesn’t publish policy so I can not add policy into my BizTalk application using script. If I need to manually change the policy status from “Not Published” to “Published”, then obviously it is not acceptable. The good news is I have source code. By changing line 261 of program.cs file from

databaseStore.Save(rulesetsToImport) to databaseStore.Save(rulesetsToImport,true), I can publish policies successfully.

        if (VerifyImport(databaseStore, rulesetsToImport, vocabulariesToImport, vocabulariesToImportAndPublish))

            {

                // no conflicts, so load them in

                try

                {

                    DisplayVersions(“Importing “, vocabulariesToImportAndPublish);

                    databaseStore.Save(vocabulariesToImportAndPublish, true);

                    DisplayVersions(“Importing “, vocabulariesToImport);

                    databaseStore.Save(vocabulariesToImport, true);

                    DisplayVersions(“Importing “, rulesetsToImport);

(line 261)                    databaseStore.Save(rulesetsToImport,true);

                }

}

 
 

Once the last issue is resolved, I can simple wrap the tool using MSBuild EXEC task to import BizTalk policies automatically.

 
 

<!– Import policy file –>

<Target
Name=ImportPolicy >

<Exec
Command =“$(BTSTools)\ImportExportRuleStore” -$(BindingFilePath)\$(PolicyFileName)/>

</Target>

 
 

<!– Add Policy to BizTalk application –>

<Target
Name=AddPolicy>

 <Exec
Command =“$(BTSPath)\BTSTask” AddResource /ApplicationName:$(BTAppName) /Type:System.BizTalk:Rules /Name:$(PolicyName) /Version:$(PolicyVersion)/>

</Target>

 
 

I need to automate The BizTalk deployment process for my current client. Surprisely, the BizTalk project file created by VS.net 2005 and 2008 doesn’t work with MsBuild. Although Scott Colestock developed a framework to deploy BizTalk using Nant, I really like a solution to MsBuild BizTalk projects.

 
 

There are a few solutions discussed and developed by a few folks. The SDC Tasks Library
is very close to what I need as long as it works as it claims. One of great examples comes from
Stephen Thomas’s blog. He used this task library ( Please not the original library is not available from GotDotNet web site ) to demonstrate that it possible to stop and remove a BizTalk application, create receive and send ports, start BizTalk application etc. using MsBuild customized tasks. One thing that doesn’t work in his example is to import a binding file although he can create send/receive ports. I got a workaround solution using BTSTask. I replaced the ImportBinding target with the following XML and successfully imported the binding file.

 
 

<Target
Name=ImportBinding >

            <Exec
Command =“$(BTSInstallLocation)\BTSTask” ImportBindings /ApplicationName:$(BTApplicationName) /Source:c:\SampleDeployment\Binding\Binding.xml/>

</Target>  

 
 

Deploying BizTalk application is a challenging task, which requires some special knowledge beyond desktop or web application deployment. In this blog, I will discuss some very common deployment issues and their solutions.

I usually choose manually deploy BizTalk application to other computers due to the time constraint to write automation script. A typical deployment cycle consists of three steps. First, prepare BizTalk application for deployment. I usually deploy BizTalk application to my local BizTalk server, then test it to ensure it works properly. I will check the value of Application Name of the project property pages to ensure it is specified properly. If the application name is not defined, it will be deployed to the default BizTalk application, BizTalk Application 1. Once it’s up and running, I will add some resource files to the application such as binding file for a target environment. Second, export BizTalk application. BizTalk Deployment Wizard is an excellent tool to export BizTalk application to an MSI file. Finally, import BizTalk application. I use BizTalk Administration Console to import the BizTalk application. If the previous version of the same application is deployment, I will uninstall and delete the previous BizTalk application before importing.

Above procedure seems to be simple. Especially, in the second step the BizTalk Deployment Wizard tool greatly simplifies the deployment process by creating an MSI file in matter of a few minutes. For any real world BizTalk application, however, we still need to pay attention to some common “minor” things to save us hours to troubleshoot deployment problems.

#1 Forgot to register artifacts

One of unique characteristics of BizTalk application development is that BizTalk artifacts including .Net assembly need to be registered in the BizTalk management database in the deployment time. This is why simply copying assembly dlls into GAC wouldn’t guarantee the application will run. In the runtime, BizTalk server will read the metadata from the database instead of using reflection in order to improve performance.

 

#2 MSI didn’t install assemblies into GAC

Did you ever wonder why MSI didn’t install your assembly into GAC? In order to install assemblies into GAC, the assemblies must be marked for a specific action such as file import, file install or add resource before exporting BizTalk application to an MSI.

 


 #3 Do not use binding file effectively

Manually creating settings such as send/receive ports is tedious and error-prone. Binding file provides a mechanism to simplify this process. We can export settings from our development environment, then modify it and import it to another machine. If the BizTalk application exists in the target machine, we can export a binding file from the target machine, for example, change the database connection string and/or assembly versions , then add it into the local BizTalk application before exporting. Alternatively, we can store all binding files into the source control system.

 

#4 Forgot to configure the security data

The exported binding file usually doesn’t include some sensitive data due to security concerns. For example, database connection password, POP3 password etc. When testing our BizTalk application, we can find the SQL adapter throw an exception, which indicates the database connection failure. In this case, we can either manually to specify the password or modify the binding file.

#5 Do not understand the difference between Import or install MSI

Although exported MSI could be installed just like any MSI files, it’s not common practice for BizTalk server in that installation doesn’t register artifact into BizTalk management database. Instead, we should import BizTalk MSI using BizTalk Server Administration console tool. The import process will add metadata into the database and copy files.

#6 Forgot to start host

Orchestration assemblies need to be loaded at runtime. Once we redeploy them, we need to stop and start BizTalk host.

Many applications could have their own deployment requirement. For instance, deploy policy and/or modify rules. It’s always a good idea to document the BizTalk deployment process for a particular application. Ultimately, we would like to see our BizTalk application deployment is a repeatable and quick process. Automation would be the answer only if we have time to create scripts or we have a deployment framework to allow us to create such scripts quickly.

Deploying versioned class library assembly in BizTalk is not straightforward process. The major problem is the BizTalk loads assemblies based upon the data stored in BizTalk management database instead of the manifest in assembly. Even if you sign the class library assembly and register it in the GAC, the end point such as orchestration or rule engine still could fail to locate it. Here is a typical error message you could see in the Event Log:
 

Could not load file or assembly ‘YourAssemblyName, Version=1.1.0.0, Culture=neutral, PublicKeyToken=64aa36518e843890′ or one of its dependencies. The system cannot find the file specified.

 

One of approach I used to solve this problem is to modify BTSNTSvc.exe.config in the C:\Program Files\Microsoft BizTalk Server 2006\, then add a couple of lines xml content to redirect assembly from old version to new version. Let’s see if you have a class library assembly called “YouClassLibraryAssemblyName”, the old version is 1.1.0.0, the new version is 1.1.1.0, you can specify the bindingRedirect like this.

 

<?xml version=”1.0″ ?>

<configuration>

<runtime>

<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>

<probing privatePath=”BizTalk Assemblies;Developer Tools;Tracking;Tracking\interop” />

<dependentAssembly>

<assemblyIdentity name=”YourClassLibraryAssemblyName”

publicKeyToken=”64aa36518e843890″

culture=”neutral” />

<bindingRedirect oldVersion=”1.1.0.0″

newVersion=”1.1.1.0″/>

</dependentAssembly>

</assemblyBinding>

</runtime>

</configuration>

In BizTalk 2004, failed messages are placed into the message box and suspended, therefore your BizTalk application cannot subscribe these failed messages and use these messages easily for some interesting things such as failure troubleshooting and message repairing. BizTalk 2006 provides a new feature, failed message routing, which allows you to enable routing for the failed messages. For instance, you can rout the message to a send port. Here is a simple and quick way to configure failed message routing.

 
 

First, you create a receive port ( MyReceivePort ) and ensure you check the “Enable routing for failed message‘. This is important because the default behavior of BizTalk 2006 is the same as that of BizTalk 2004.

 


 
 

When this property is checked, A set of properties will be promoted. Such as,

ErrorReport.ErrorType

ErrorReport.Description

ErrorReport.FailureCode

ErrorReport.MessageType

ErrorReport.ReceivePortName

ErrorReport.SendPortName

ErrorReport.InboundTransportLocation

ErrorReport.OutboundTransportLocation

ErrorReport.RoutingFailureReportID

 
 

You leverage these context properties in your application by subscribing them at send/receive port and/or orchestration.

 

Next, you create a send port with file type and set ErrorReport.ReceivePortName == MyReceivePort. That’s it! If you pass a bad message, you should see it’s saved as a file in the FailedMsgsPort port.

 
 


 
 

If you want to build a robust BizTalk application to intelligently repair some bad messages, you can subscribe the failed message in the orchestration. Please note BTS.MessageType and ErrorReport.MessageType are different. BTS.MessageType will only be prompted when a message successfully passes a pipeline.

After working with ASP.Net Ajax and Telerik RadAjax, I think RadAjax is a good tool for rapid ASP.Net programming. If you need to get things done quickly with decent UI, you should consider RadAjax and Telerik web controls.

Telerik’s RadAjax framework allows you to take a regular ASP.Net application and AJAX-enable it with no coding or changes to your page life cycle. No client side javascript, no server side coding – just drop a component on your form and configure it with the smart tag editor and you are good to go! The framework automatically replaces Postbacks with AJAX callbacks. It preservers changes to viewstate, preserves the normal page life cycle, persists form values, reruns client side javascript as needed, and supports standard client side validation. In other words, it works well out of the box with most ASP.Net 1.1 or 2.0 applications, and many third party components

Although “no coding” seems to be a good slogan, you still need to understand some basic Ajax concept and how Telerik works to get your job done if you’re programming daily.

You can use RadAjaxPanel and/or RadAjaxManager to build Ajax enabled page. RadAjaxPanel is quicker to get things done if the requirement is not complicated. RadAjaxManager is a little bit complicated, however it has lower level APIs which you can leverage.

Understanding RadAjaxPanel

Let’s imaging we put the AP.Net calendar control on the form and label on the bottom of the form. When we click the date, the label will be changed and you will see the page flickers due to the page refresh.


Here is the content in the aspx page

<form id=”form1″ runat=”server”>

<div>

<radA:RadAjaxPanel ID=”RadAjaxPanel1″ runat=”server” Height=”200px” Width=”300px”>

<asp:Calendar id=”Calendar1″ runat=”server” __designer:wfdid=”w1″

OnSelectionChanged=”Calendar1_SelectionChanged”>

</asp:Calendar>

<BR />

<asp:Label id=”lblDateSelected” runat=”server”

__designer:wfdid=”w2″ Width=”258px”></asp:Label>

</radA:RadAjaxPanel>

</div>

</form>

After surrounding the calendar and label control, you won’t see the screen refresh. It sounds simple however it has a major flaw, everything that is inside the panel is re-rendered for every AJAX callback, whether it changed or not.

Understanding RadAjaxManager

When the page is complicated with some complicated controls such as GridView or TreeView, the performance of RadAjaxPanel. In this case, a better approach is to choose RadAjaxManager which could be used more precisely control the initiator ( trigger ) controls and target controls.

The Initiator is the control that causes a Postback that you wish to convert to an AJAX callback, for

instance a Button, or some control that has it’s AutoPostback property set.

The Targets are the controls that are to be re-rendered after the callback (presumably because the

callback changes them). The target can be a list of individual controls, or containers, like ASP Panels,

RadAjaxManager maintains a list of AjaxSetting with one control as an Initiator, and one or more controls as Targets. A requirement for this to work is that the controls that are specified in the AjaxSettings are rendered with an ID attribute in the client side HTML. As you know, when you set the visibility of asp.net to false, then there is no HTML content will be rendered, which could cause Javascript error when using RadAjaxManager because it expects an ID. To resolve this issue, you can use a DIV element to surround your ASP.net controls.

<div id=”divEnd” runat=server>

<radCln:RadDatePicker ID=”dpEnd” runat=”server” Width=”100px”>

<DateInput Title=”" PromptChar=” ” TitleIconImageUrl=”"

DisplayPromptChar=”_” CatalogIconImageUrl=”"

TitleUrl=”" Description=”"></DateInput>

</radCln:RadDatePicker>

</div>

You can only have one RadAjaxManager per page. You can not mix RadAjaxManagers and RadAjaxPanels in the same page according to the current version of Telerik Ajax.

Rewirte the above example using RadAjaxManager:

<radA:RadAjaxManager ID=”RadAjaxManager1″ runat=”server”>

<AjaxSettings>

<!– AjaxControlID: Initiator –>

<radA:AjaxSetting
AjaxControlID=”ddlDateRange”>

<UpdatedControls>

<!– one or more target controls –>

<radA:AjaxUpdatedControl ControlID=”dpStart”

LoadingPanelID=”AjaxLoadingPanel1″ />

<radA:AjaxUpdatedControl ControlID=”divEnd”

LoadingPanelID=”AjaxLoadingPanel1″ />

</UpdatedControls>

</radA:AjaxSetting>

</AjaxSettings>

</radA:RadAjaxManager>

Initiator in the User Control

There are some limitations in the RadAjaxManager. For instance you can’t add it into the Web User Control because the RadAjaxManager needs to go on the page that hosts this control. In order to get RajAjaxManager to work with user control, you need to create a method to allow the host page to inject the RajAjaxManager into the user control. For instance:

public void ConfigureAjax( RadAjaxManager ajm )

{

ajm.AjaxSettings.AddAjaxSetting( ddlDateRange, dpStart, AjaxLoadingPanel1 );

ajm.AjaxSettings.AddAjaxSetting( ddlDateRange, divEnd, AjaxLoadingPanel1 );

}

Using RadAjaxManager in Master Page

If you want to use the RadAjaxManager in a Master Page context, it is most likely that you will have the RadAjaxManager in the Master Page, and the Ajax Initiators and Targets could be in any combination of the Master Page or the Content Forms. Either way, you will need to set up your AjaxSettings programmatically, as the RadAjaxManager Property Builder will not be able to see into the Content Pages.

Sample code in the content page

protected void pbContent_Click(object sender, EventArgs e)

{

Label lbl = (Label)this.Master.FindControl(“lblMaster”);

lbl.Text = “Changed from Content ” + DateTime.Now.ToString();

}

Sample code in the master page

protected void pbMaster_Click(object sender, EventArgs e)

{

Label lbl = (Label) this.cphMain.FindControl(“lblContent”);

lbl.Text = “Changed from Master ” + DateTime.Now.ToString();

}

So where we should hook up Ajax? The answer is anywhere. The Ajaxsetting could be set in the master page, content page or both. You need to determine where to put it to get page functional and maintainable in your project although you’re most likely will put the code in the content page.

protected void Page_Load(object sender, EventArgs e)

{

RadAjaxManager ajm = (RadAjaxManager)this.Master.FindControl(“ajmMaster”);

Button btn = (Button)this.Master.FindControl(“pbMaster”);

ajm.AjaxSettings.AddAjaxSetting(btn, this.lblContent);

Label lbl = (Label)this.Master.FindControl(“lblMaster”);

ajm.AjaxSettings.AddAjaxSetting(pbContent, lbl);

}

With Entity Framework, you can build some sophisticated applications elegantly. What’s the magic under the hood? Below is the Entity Framework Architecture

 
 


 
 

Data Provider

The lowest layer in the Entity Framework is data provider. It translates the common SQL languages such as LINQ via command tree to the native SQL expression, then execute it against the specific DBMS system. Currently only SQL Server Provider is available. The rumor said the Oracle provider is under development. In the future version, Microsoft will develop more data providers to support other data sources such as web services.

 
 

EntityClient Provider.

The EntityClient provider exposes the entity layer to the upper layer. It allows you to write code to query data base using Entity SQL, an entity ware language. The entity model is mapped to the database table via the mapping specification language (MSL ) and mapping engine.

The query pipeline of EntityClient provider compiles the entity sql text to the command tree, then pass it to the data provider.

EntityClient doesn’t materialize object from the data set. Some data intensive application such as Reporting application can leverage the performance benefit of EntityClient layer.

 
 

Object Services.

Object Service is ORM layer of Entity Framework. It materializes the data result to the object instances of entities. Object Service provides rich ORM features such as change tracking, lazy loading and primary key mapping. Both LINQ and Entity SQL could be used to write query.

 
 

Metadata Service

Metadata Service provides centralized API to access the metadata stored in the CSDL, MSL, SSDL and assembly files. Metadata such as entities, associations, entityset is essential for building highly flexible and powerful runtime applications and design-time tools.

 
 

Design Tools.

The Entity Framework provides many tools integrated with visual studio 2008 to improve productivity.

 
 

Entity Framework Tools

Creating entity data model, entity class and mapping the entity layer ( CSDL ) to the source layer (SSDL) could be a labor intensive work for a large enterprise application. ADO.Net 3.5 provides several tools to make you more productive while working with the Entity Framework in the design time.
Entity Data Model Wizard
Generate edmx file which is used by Entity Data Model Designer to display the model graphically. Generate entity classes; You start the wizard by adding an ADO.Net Entity Data Model to your project.
Entity Data Model Designer
Add/Delete/Modify Entities; Properties; Association of the conceptual model. Validate model and mapping; Report Error;

Entity Mapping Details
Map entity types or associations to database tables and columns.
Add a condition. It’s important to create table-per-hierarchy ( TPH ) inheritance mapping.
Entity Model Browser
View the Entity Data Model in tree view style.
EdmGen.exe
A command-line used for working with the Entity Data Model (EDM).
C:\WINDOWS\Microsoft.NET\Framework\v3.5\edmgen.exe
Microsoft (R) EdmGen version 3.5.0.0

Copyright (C) Microsoft Corporation 2007. All rights reserved.

EdmGen Options

/mode:EntityClassGeneration Generate objects from a csdl file

/mode:FromSsdlGeneration Generate msl, csdl, and objects from an ssdl file

/mode:ValidateArtifacts Validate the ssdl, msl, and csdl files

/mode:ViewGeneration Generate mapping views from ssdl, msl,and csdl files

/mode:FullGeneration Generate ssdl, msl, csdl, and objects from the database

/project:<string> The base name to be used for all the artifact files (short form: /p)

/provider:<string> The name of the Ado.Net data provider to be used for ssdl generation. (short form: /prov)

/connectionstring:<connection string> The connection string to the database that you would like to connect to (short form: /c)

/incsdl:<file> The file to read the conceptual mode from

/refcsdl:<file> A csdl file that contains types that the /incsdl file is dependent upon

/inmsl:<file> The file to read the mapping from

/inssdl:<file> The file to read the storage model from

/outcsdl:<file> The file to write the generated conceptual model to

/outmsl:<file> The file to write the generated mapping to

/outssdl:<file> The file to write the generated storage model to

/outobjectlayer:<file> The file to write the generated object layer to

/outviews:<file> The file to write the pre generated view objects to

/language:CSharp Generate code using the C# language

/language:VB Generate code using the VB language

/namespace:<string> The namespace name to use for the conceptual model types

/entitycontainer:<string> The name to use for the EntityContainer in the conceptual model

/help Display the usage message (short form:

/?)

/nologo Suppress copyright message

Examples

To generate a full Entity Model from the Northwind sample database.

EdmGen /mode:FullGeneration /project:Northwind /provider:System.Data.SqlClient /connectionstring:”server=.\sqlexpress;integrated security=true;

database=northwind”
To generate an Entity Model starting from an ssdl file.
EdmGen /mode:FromSSDLGeneration /inssdl:Northwind.ssdl /project:Northwind

To validate an Entity Model.
EdmGen /mode:ValidateArtifacts /inssdl:Northwind.ssdl /inmsl:Northwind.msl

/incsdl:Northwind.csdl


 

In the object world, Inheritance is natural thing. However the flat data model cannot be easily mapped to the hierarchy object model. Entity Framework provide TPT and TPH to solve this problem.  

Below is a diagram I draw based on the MSDN Table-per-type sample. The right side is a list of entity types in the source layer while the left side is a list of entity types in the entity layer ( or conceptual layer). In the conceptual layer, the DeptMusic, DeptEnginerring and DeptBussiness are derived from base type Department. That is, four tables have corresponding entity types. Therefore this inheritance solution is called Table-per-type ( TPT ). Although the Department and DeptBusiness tables have no relationship with each other, the primary keys of these tables are mapped to the same DepartmentID of the Department base type.



 

Table-per-hierarchy ( TPH ) is another way to create inheritance entity model in the EDM. The MSDN sample uses one person to hold the persisted data from the Student, Administrator, instructor and Person entities. As you might notice, Person is the base type in the hierarchy while Student, Administrator and Instructor are derived types. The PersonCategory column of the Person table is called discriminator column. If the value of PersonCategory is 0 in the database, when the data is materialized to object via Entity Framework, a person object will be created. A value of 1,2,3 indicate the Student, Instructor and Administrator types respectively. You can use Entity Mapping Detail window to specify discriminator columns and values.


Older Posts »

Follow

Get every new post delivered to your Inbox.