Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il codice utilizzato dall'applicazione HRSkills illustra diverse funzionalità di Entity Data Model (EDM). Gli schemi descritti negli argomenti precedenti relativi a HRSkills costituiscono la base per le entità e le associazioni utilizzate dal codice in questa sezione. Per informazioni sulle entità e sulle associazioni di questo esempio, vedere Applicazione WinApp relativa alle competenze delle risorse umane (applicazione di esempio EDM). Per informazioni sui metadati di archiviazione, vedere Metadati di archiviazione per l'applicazione per la valutazione delle competenze delle risorse umane (applicazione di esempio EDM). Per la specifica di mapping, vedere Specifica di mapping per l'applicazione per la valutazione delle competenze delle risorse umane (applicazione di esempio EDM).
I tipi progettati negli schemi e mappati all'archivio sono compilati come modello a oggetti programmabile. I dati in questo modello possono essere programmati utilizzando la sintassi CLR (Common Language Runtime) senza query SQL incorporate come stringhe nel codice.
L'applicazione illustra l'associazione dati alle entità, le query con parametri e l'utilizzo delle proprietà di navigazione nelle associazioni. Le associazioni consentono di connettere le entità Employees alle entità References, le entità Employees alle entità Skills e le entità Skills alle entità SkillInfo che contengono informazioni sulle competenze.
File di configurazione e stringa di connessione
Per l'utilizzo del modello a oggetti, è necessaria una connessione al database in cui sono archiviati i dati dell'applicazione. È inoltre necessaria una connessione dell'entità agli oggetti di runtime forniti dalla DLL compilata dagli schemi. Per ulteriori informazioni sulla compilazione del modello a oggetti dagli schemi, vedere Procedura: Procedura: utilizzare EdmGen.exe per generare un modello EDM (Entity Framework).
Il file exe.config contiene una stringa di connessione utilizzata per connettersi a un database di SQL Server e per stabilire una connessione dell'entità. Dopo che è stata stabilita una connessione dell'entità, è possibile accedere alle entità e alle associazioni nel modello a oggetti dal codice.
Il testo della stringa di connessione deve essere aggiunto al file exe.config dallo sviluppatore. Questa applicazione specifica la classe HRSkills. L'assegnazione providerName="System.Data.EntityClient" specifica una connessione dell'entità che utilizza lo schema di mapping definito in Specifica di mapping per l'applicazione per la valutazione delle competenze delle risorse umane (applicazione di esempio EDM).
La stringa di connessione identifica anche il server utilizzato dalla connessione SQL: provider connection string="server=servername;. provider connection string="server=servername;.
Nell'esempio seguente viene illustrato il contenuto del file exe.config.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="HRSkills"
connectionString='metadata=.;
provider=System.Data.SqlClient;
provider connection string="server=serverName;
database=HRSkills;
integrated security=true;
multipleactiveresultsets=true"'
providerName="System.Data.EntityClient"/>
</connectionStrings>
</configuration>
Codice dell'applicazione
Nel codice seguente sono contenuti i gestori eventi convenzionali inizializzati ed eseguiti da un Windows Form che funge da interfaccia utente in questa applicazione di esempio. Le direttive using del preprocessore includono gli spazi dei nomi necessari per eseguire query per la ricerca di dipendenti, referenze, competenze e informazioni sulle competenze. La direttiva using finale include lo spazio dei nomi HRSkillsModel che contiene le classi di runtime per le entità e le relazioni nel modello a oggetti definito e compilato per questa applicazione, come descritto negli argomenti precedenti di questa sezione.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.Mapping;
using System.Data.Objects;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.Metadata;
using System.Linq;
using HRSkillsModel;
namespace HR_Skills_WinApp
{
public partial class Form1 : Form
{
HRSkills DB = new HRSkills();
public Form1()
{
InitializeComponent();
Viene dichiarata e inizializzata una variabile per ObjectContext: HRSkills DB = new HRSkills. La connessione è contenuta in ObjectContext e inizializzata nelle parentesi try, come illustrato nel segmento di codice che segue. Durante il test dell'applicazione è possibile leggere gli eventuali messaggi di errore di connessione.
La query iniziale utilizzata per visualizzare tutti gli oggetti Employees presenti nell'archivio utilizza l'entità Employees. La classe Employees è un oggetto ObjectQuery<T> in ObjectContext che restituisce tutte le entità dipendente.
Per visualizzare i risultati della query Employees viene utilizzato un controllo DataGridView. Le colonne vengono aggiunte a DataGridView. L'oggetto BindingSource viene inizializzato su Query<T> di Employees e la proprietà DataSource del controllo esegue l'associazione dati. Utilizzando il parametro true, il database viene aggiornato quando vengono effettuate modifiche al controllo DataGrid.
public Form1()
{
InitializeComponent();
try
{
bindingSource1.DataSource = DB.Employees;
dataGridView1.DataSource = bindingSource1;
dataGridView1.Columns[0].Visible = false;
}
catch(Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString());
}
}
Dopo la visualizzazione di Employees nel controllo DataGridView, gli utenti dell'applicazione possono fare clic su qualsiasi riga per ottenere l'oggetto Skills associato all'entità Employee visualizzata nella riga. Tramite una nuova query viene individuato l'oggetto EmployeeId dell'entità Employee i cui dati sono visualizzati in DataGridView. EmployeeId non è visualizzato in DataGridView, ma viene conservato come riferimento e utilizzato da una query ObjectQuery<T> con parametri su Employees. Il parametro viene creato e inizializzato nella riga: ObjectParameter param = new ObjectParameter("p", empId). ObjectParameter viene utilizzato nella query: DB.Employees.Where("it.EmployeeId = @p", param).First(). DB.Employees.Where("it.EmployeeId = @p", param).First().
Dopo che la classe relativa ai dipendenti è stata identificata e restituita dalla query, l'associazione Skill_Employee viene utilizzata per individuare tutte le entità Skills associate al dipendente. In una riga di codice viene utilizzata la proprietà di navigazione del dipendente per caricare dal database tutti gli oggetti Skills associati al dipendente: Skill_Employee.GetSkillsEntities(employee).Load(). Skill_Employee.GetSkillsEntities(employee).Load(). Tramite un ciclo foreach nella stessa proprietà di navigazione vengono quindi letti gli oggetti Skills associati al dipendente in un secondo controllo DataGridView.
private void dataGridView1_CellClick(object sender,
DataGridViewCellEventArgs e)
{
dataGridViewSkills.Columns.Clear();
// Get the Id of the Employee and
Guid empId = new Guid(dataGridView1.CurrentRow.Cells[0].Value.ToString());
// Find the Employee.
ObjectParameter param = new ObjectParameter("p", empId);
try
{
if (null != DB.Employees.Where(
"it.EmployeeId = @p", param).First())
{
Employees employee = DB.Employees.Where(
"it.EmployeeId = @p", param).First();
employee.Skills.Load();
List<Skills> skillsList = new List<Skills>();
foreach (Skills skill in employee.Skills)
{
skillsList.Add(skill);
}
bindingSource2.DataSource = skillsList;
dataGridViewSkills.DataSource = bindingSource2;
dataGridViewSkills.Columns[0].Visible = false;
dataGridViewSkills.Columns[2].Width = 300;
richTextBox1.Clear();
// Provide EmployeeId for new skill or
// reference association.
textBoxSkillEmployeeId.Text =
employee.EmployeeId.ToString();
textBoxSkillEmployeeAlias.Text = employee.Alias;
textBoxRefEmployeeId.Text =
employee.EmployeeId.ToString();
textBoxRefEmployeeAlias.Text = employee.Alias;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.ToString());
}
}
Il metodo successivo consente di visualizzare le informazioni sugli oggetti Skills contenuti dalle entità SkillInfo in un controllo RichTextBox nell'interfaccia utente. Sulle entità SkillInfo associate alle entità Skills viene eseguita una query e tali entità vengono visualizzate utilizzando lo stesso processo del metodo precedente. Un query accetta SkillId come parametro e consente di trovare un'entità Skills specifica. La proprietà di navigazione dell'entità Skills viene esplorata per trovare tutte le entità SkillInfo associate alla competenza.
Le proprietà delle entità SkillInfo contengono URL che consentono di individuare informazioni aggiuntive sugli oggetti Skills associati. L'URL di ogni entità SkillInfo viene visualizzato nella casella di testo in formato RTF.
All'entità employee associata all'entità Skills utilizzata in questo metodo è possibile accedere anche dall'entità Skills tramite l'associazione Skill_Employee. Una referenza per il dipendente viene caricata dal database utilizzando una riga di codice: Skill_Employee.GetEmployeesRef(skill).Load(). Il dipendente viene assegnato a una variabile in una seconda riga: Employees employee = Skill_Employee.GetEmployees(skill). L'alias del dipendente viene scritto nella casella di testo in formato RTF.
Le referenze associate al dipendente vengono ottenute dall'associazione Reference_Employee. Il nome, la posizione e l'indirizzo di posta elettronica di tutte le referenze sono contenuti nelle proprietà delle entità References. Queste informazioni sono visualizzate nell'oggetto Rich Text Box per integrare i collegamenti alle informazioni sulle competenze del dipendente.
private void dataGridViewSkills_CellClick(object sender,
DataGridViewCellEventArgs e)
{
richTextBox1.Clear();
// Write the name of the skill and brief
// description to richtext box.
richTextBox1.Text = richTextBox1.Text + "Skill Name: "
+ dataGridViewSkills.CurrentRow.Cells[1].
Value.ToString() + "\n" +
dataGridViewSkills.CurrentRow.Cells[2].
Value.ToString();
// Create ObjectParameter from the SkillId property
// and get the Skill.
Guid skillId =
new Guid(dataGridViewSkills.CurrentRow.Cells[0].Value.ToString());
ObjectParameter param =
new ObjectParameter("p", skillId);
Skills skill = DB.Skills.Where("it.SkillId = @p",
param).First();
// Load the SkillInfo entities using
// SkillInfo_Skill association.
skill.SkillInfo.Load();
foreach (SkillInfo skillInfo in skill.SkillInfo)
{
richTextBox1.Text = richTextBox1.Text +
"\n\nSkill Information: " + skillInfo.URL +
"\n";
}
dataGridView1.ClearSelection();
// Load the Employee associated with the
// Skill using Skill_Employee association.
skill.EmployeeReference.Load();
Employees employee = skill.Employee;
if (null == employee) return;
// Write the alias property of the Employee to rich text
// box and heading for references.
richTextBox1.Text = richTextBox1.Text +
"\n\nEmployee: " + employee.Alias +
"\n\n" + "References:";
// Load References of Employee using
// Reference_Employee association.
employee.References.Load();
foreach (References reference in employee.References )
{
// Write reference LastName and Position to
// richtext box.
richTextBox1.Text = richTextBox1.Text + "\n" +
reference.FirstName + " " + reference.LastName +
" Position: " + reference.Position +
" Email: " + reference.Email;
}
// Provide SkillId for new SkillInfo if needed.
textBoxSkillInfoSkillId.Text = skill.SkillId.ToString();
for (int i = 0; i < dataGridView1.RowCount; i++)
{
// Check to see if this is the employee associated
// with the skill.
if (dataGridView1.Rows[i].Cells[0].Value.ToString()
== employee.EmployeeId.ToString())
{
dataGridView1.Rows[i].Selected = true;
dataGridView1.CurrentCell = dataGridView1[1, i];
// Break out when the row is found.
break;
}
}
}
Questa applicazione consente di eseguire una query su Employees per determinare le competenze dei dipendenti oppure di eseguire una query su Skills per determinare quali dipendenti dispongono delle competenze a cui si fa riferimento nel sistema. Il metodo seguente accetta un input dell'utente da un controllo TextBox e consente di cercare i dipendenti con le competenze descritte dall'input dell'utente.
Questa query su Skills viene avviata quando l'utente digita le parole chiave, separate da uno spazio, nel controllo TextBox. Quando si fa clic sul pulsante SkillSearch, l'elenco di parole chiave viene creato dal testo di input nel controllo TextBox di ricerca.
Ogni parola chiave nell'elenco viene ottenuta utilizzando un ciclo foreach. Viene creato un oggetto ObjectParameter da ogni parola chiave: ObjectParameter param = new ObjectParameter("p", "%" + keyword + "%"). Ogni nuovo valore di parola chiave per il parametro viene utilizzato in una nuova query per la ricerca delle proprietà SkillName e BriefDescription di tutte le entità Skills nel sistema: skillsQuery = DB.Skills.Where("it.BriefDescription Like @p OR it.SkillName Like @p", param). skillsQuery = DB.Skills.Where("it.BriefDescription Like @p OR it.SkillName Like @p", param).
I risultati della query sono entità Skills in cui il nome o la descrizione della competenza contiene una o più parole chiave. Questi risultati vengono letti nel controllo DataGridView di Skills. È possibile fare clic sulle righe della visualizzazione in DataGridView per ottenere informazioni sulle competenze e sulle referenze del dipendente. Facendo clic su una riga del controllo DataGridView di Skills viene utilizzato il gestore come descritto in precedenza e gli URL di SkillInfo, nonché gli oggetti Alias e References dei dipendenti vengono visualizzati dal controllo Rich Text Box nell'interfaccia utente.
private void buttonSkillSearch_Click(object sender, EventArgs e)
{
dataGridViewSkills.DataSource = null;
dataGridViewSkills.Columns.Clear();
try
{
dataGridViewSkills.Columns.Add("idSkill",
"Skill Id");
dataGridViewSkills.Columns.Add("nameSkill",
"Skill");
dataGridViewSkills.Columns.Add("descSkill",
"Description");
dataGridViewSkills.Columns[2].Width = 300;
// Make a list of keywords to search for in
// Skill entity name and description.
List<string> keywords = new List<string>();
int i = 0;
int j = 0;
while (i < textBoxKeywords.Text.Length)
{
j = textBoxKeywords.Text.IndexOf(" ", i);
if (-1 == j) j = textBoxKeywords.Text.Length;
keywords.Add(
textBoxKeywords.Text.Substring(i, j - i));
i = ++j;
}
foreach (string keyword in keywords)
{
// Create ObjectParameter from each keyword
// and search properties of Skills.
ObjectParameter param = new ObjectParameter(
"p", "%" + keyword + "%");
ObjectQuery<Skills> skillsQuery =
DB.Skills.Where(
"it.BriefDescription Like @p " +
"OR it.SkillName Like @p", param);
foreach (Skills skill in skillsQuery)
{
// Create an array of Skill property
// strings for display.
string[] columnValues =
new string[3] {skill.SkillId.ToString(),
skill.SkillName,
skill.BriefDescription};
foreach (DataGridViewRow row in
dataGridViewSkills.Rows)
{
// break if duplicate of
// Skill already found.
if (row.Cells[0].Value != null)
{
if (row.Cells[0].Value.ToString()
== columnValues[0])
{
break;
}
}
}
dataGridViewSkills.Rows.Add(columnValues);
}
}
// Hide EmployeeId in datagrid,
// but keep for reference.
dataGridViewSkills.Columns[0].Visible = false;
richTextBox1.Clear();
}
catch(Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString(),
"Error Message");
}
}
Il gestore seguente consente agli utenti di premere <INVIO> nell'oggetto TextBox utilizzato per avviare la ricerca delle parole chiave anziché fare clic sul pulsante Search.
private void textBoxKeywords_PreviewKeyDown(object sender,
PreviewKeyDownEventArgs e)
{
// Provide Enter activation in Search text box.
if(e.KeyCode.Equals(Keys.Return))
buttonSkillSearch_Click(this, System.EventArgs.Empty );
}
Il gestore seguente viene utilizzato quando l'utente invia le informazioni che saranno utilizzate per creare una nuova entità Employees. Tramite il metodo vengono innanzitutto convalidate le informazioni di input, in questo caso solo verificando che l'input di textBoxLastName e textBoxAlias sia in entrambi i casi costituito da testo. Dopo aver creato la nuova entità Employees, prima di aggiungere la nuova entità al sistema tramite il metodo viene eseguito un controllo per determinare se tale entità è un duplicato di un'entità Employee già presente nell'archivio.
Per la creazione della nuova entità Employees è necessario un nuovo oggetto Guid per la proprietà EmployeeId. Le proprietà LastName, FirstName, Alias e Email della nuova entità vengono assegnate dai contenuti delle caselle di testo, dove il testo viene immesso dall'utente.
Per aggiungere un'entità al sistema sono necessarie due chiamate al metodo. La prima consente di aggiungere il nuovo oggetto al contesto dell'oggetto: DB.AddToEmployees(newEmployee). La nuova entità non viene salvata nel database fino a quando non viene effettuata la seconda chiamata al metodo: DB.SaveChanges().
private void buttonSubmitEmployee_Click(object sender,
EventArgs e)
{
try
{
if ("".Equals(textBoxLastName.Text) ||
"".Equals(textBoxEmployeeAlias.Text))
{
MessageBox.Show("Incomplete Information");
return;
}
// Create new Employee and add to storage.
Employees newEmployee = new Employees();
newEmployee.EmployeeId = Guid.NewGuid();
newEmployee.LastName = textBoxLastName.Text;
newEmployee.Alias = textBoxEmployeeAlias.Text;
newEmployee.FirstName = textBoxFirstName.Text;
newEmployee.Email = textBoxEmployeeEmail.Text;
DB.AddToEmployees(newEmployee);
// Check for duplicate.
ObjectQuery<Employees> dbEmplQuery =
DB.Employees.Where("it.Alias = @p",
new ObjectParameter("p", newEmployee.Alias));
if (!dbEmplQuery.Any())
DB.SaveChanges();
//Refresh the Employees datagrid.
EmployeesLabel_DoubleClick(this, null);
textBoxFirstName.Clear();
textBoxLastName.Clear();
textBoxEmployeeAlias.Clear();
textBoxEmployeeEmail.Clear();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString(),
"Error Message");
}
}
Il gestore seguente viene utilizzato quando l'utente invia le informazioni che saranno utilizzate per creare una nuova entità Skills.
private void buttonSubmitSkill_Click(object sender, EventArgs e)
{
try
{
if ("".Equals(textBoxSkillShortName.Text) ||
"".Equals(textBoxSkillBriefDescription.Text) ||
"".Equals(textBoxSkillEmployeeId.Text))
{
MessageBox.Show("Incomplete Information");
return;
}
// Create new Skills entity.
Skills newSkills = new Skills();
newSkills.SkillId = Guid.NewGuid();
newSkills.SkillName = textBoxSkillShortName.Text;
newSkills.BriefDescription =
textBoxSkillBriefDescription.Text;
DB.AddToSkills(newSkills);
// Make a Guid of EmployeeId of Employee who
// has this Skill and use it in query.
Guid empId =
new Guid(textBoxSkillEmployeeId.Text);
ObjectParameter param =
new ObjectParameter("p", empId);
Employees employee = DB.Employees.Where(
"it.EmployeeId = @p", param).First();
// Add the Skill to the Skill_Employee association.
employee.Skills.Add(newSkills);
DB.SaveChanges();
textBoxSkillShortName.Clear();
textBoxSkillBriefDescription.Clear();
textBoxSkillEmployeeId.Clear();
textBoxSkillEmployeeAlias.Clear();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString(),
"Error Message");
}
}
Il gestore seguente viene utilizzato quando l'utente invia le informazioni che saranno utilizzate per creare una nuova entità SkillInfo.
private void buttonSubmitSkillInfo_Click(object sender,
EventArgs e)
{
try
{
if ("".Equals(textBoxSkillInfoSkillId.Text) ||
"".Equals(textBoxUrlUncSkillInfo.Text))
{
MessageBox.Show("Incomplete Information");
return;
}
// Create new SkillInfo entity.
SkillInfo newSkillInfo = new SkillInfo();
newSkillInfo.SkillInfoId = Guid.NewGuid();
newSkillInfo.URL = textBoxUrlUncSkillInfo.Text;
// Create query and find Skill to
// associate with SkillInfo.
Guid empId =
new Guid(textBoxSkillInfoSkillId.Text);
ObjectParameter param =
new ObjectParameter("p", empId);
Skills skill =
DB.Skills.Where("it.SkillId = @p",
param).First();
// Add SkillInfo to SkillInfo_Skill association.
skill.SkillInfo.Add(newSkillInfo);
DB.AddToSkillInfo(newSkillInfo);
DB.SaveChanges();
textBoxSkillInfoSkillId.Clear();
textBoxUrlUncSkillInfo.Clear();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString(),
"Error Message");
}
}
Il gestore seguente viene utilizzato quando l'utente invia le informazioni che saranno utilizzate per creare una nuova entità References.
private void buttonSubmitReference_Click(
object sender, EventArgs e)
{
try
{
if ("".Equals(textBoxRefEmployeeId.Text) ||
"".Equals(textBoxRefEmployeeAlias.Text))
{
MessageBox.Show("Incomplete Information");
return;
}
// Create new Reference and add to
// Reference_Employee association.
References reference = new References();
reference.ReferenceId = Guid.NewGuid();
reference.LastName = textBoxRefLastName.Text;
reference.Email = textBoxRefEmail.Text;
reference.Alias =
textBoxRefEmail.Text.Remove(
textBoxRefEmail.Text.IndexOf('@'));
reference.FirstName = textBoxRefFirstName.Text;
reference.Position = textBoxRefPosition.Text;
Guid empId = new Guid(
dataGridView1.CurrentRow.Cells[0].
Value.ToString());
ObjectParameter param = new ObjectParameter(
"p", empId);
Employees employee = DB.Employees.Where(
"it.EmployeeId = @p", param).First();
DB.AddToReferences(reference);
employee.References.Add(reference);
DB.SaveChanges();
textBoxRefFirstName.Clear();
textBoxRefLastName.Clear();
textBoxRefEmail.Clear();
textBoxRefPosition.Clear();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString(),
"Error Message");
}
}
Il gestore eventi seguente consente di avviare il browser Internet per visualizzare l'URL di SkillInfo scritto in Rich Text Box dal metodo precedente.
private void richTextBox1_LinkClicked(object sender,
LinkClickedEventArgs e)
{
// Display the SkillInfo URL in Web browser.
System.Diagnostics.Process.Start(e.LinkText);
}
Il gestore seguente viene utilizzato quando l'utente fa doppio clic sull'etichetta nel controllo DataGridView di Employees. La sua funzione è quella di aggiornare il controllo DataGridView di Employees quando le nuove entità Employees sono state aggiunte al sistema. Viene inoltre chiamato verso la fine del gestore buttonSubmitEmployee_Click.
private void EmployeesLabel_DoubleClick(object sender,
EventArgs e)
{
try
{
DB.Dispose(); //Dispose to refresh the data.
DB = new HRSkills();
bindingSource1.DataSource = DB.Employees;
dataGridView1.DataSource = bindingSource1;
dataGridView1.Columns[0].Visible = false;
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString(),
"Error Message");
}
}
Vedere anche
Concetti
Applicazione WinApp relativa alle competenze delle risorse umane (applicazione di esempio EDM)
Metadati di archiviazione per l'applicazione per la valutazione delle competenze delle risorse umane (applicazione di esempio EDM)
Specifica di mapping per l'applicazione per la valutazione delle competenze delle risorse umane (applicazione di esempio EDM)