Ilość wyświetleń: 12472 « powrót

SharePoint Foundation 2010 - Utworzenie listy z danych zewnętrznych MsSql z wykorzystaniem Business Data Connectivity Service i External Content Type

Wstęp

By przybliżyć Bdc w SharePoint Foundation 2010, przedstawię swój pierwszy projekt, który tworzyłem by zapoznać się z tym rozwiązaniem. Była to integracja danych z systemu ewidencji sprzętu komputerowego Ewida z SharePiont Foundation 2010 poprzez zewnętrzną listę z wykorzystaniem Business Data Connectivity Service i External Content Type.

Krótki plan czynności jakie były do zrobienia

  • Stworzenie odpowiedniego widoku w bazie danych Ewida
  • Utworzenie w Visual Studio 2010 projektu BDC Model
  • Zdefiniowanie klasy przechowującej element listy
  • Zmiana w modelu BDC atrybutów zgodnie z wcześniej utworzoną klasą
  • Zaimplementowanie testowych metod ReadList, ReadItem w celu sprawdzenia rozwiązania
  • Zmodyfikowanie projektu do automatycznego deployment'u (dla Foundation)
  • Nadanie uprawnień do BDC w SF
  • Utworzenie nowej listy bazującej na BDC
  • Zastąpienie metod testowych rzeczywistym odczytem danych
i po kolei ich realizacja

Stworzenie odpowiedniego widoku w bazie danych Ewida

Najpierw zabrałem się do tworzenia widoku, który zawierałby wszystkie potrzebne mi dane. Po pobieżnym zapoznaniu się ze strukturą bazy, która przechowuje informacje o sprzęcie i użytkownikach, utworzyłem dwa widoki.

Pierwszy to cała lista sprzętu i jego użytkowników, tutaj pozbyłem się już ewentualnych wartości null, które mogły by później sprawić kłopot SharePoint'owi

create view HardwareList as
select 
  s.C_TKey as KeyID,
  isnull(s.C_InventoryNr, '') as NrEwid,
  isnull(s.C_Manufacturer, '') as Producent,
  isnull(s.C_Model, '') as Model,
  isnull(s.C_Name, '') as Typ,
  isnull(s.C_SerialNr, '') as Sn,
  isnull(s.C_Status, '') as Stan,
  isnull(u.C_LastName, '') as Nazwisko,
  isnull(u.C_FirstName, '') as Imie,
  isnull(u.C_Department, '') as Dzial,
  isnull(u.C_Location, '') as Lokalizacja,
  isnull(u.C_RoomNr, '') as NrPokoju,
  isnull(u.C_Position, '') as Stanowisko,
  isnull(u.C_PhoneWork, '') as Telefon,
  isnull(s.C_HostName, '') as NetNazwa
from 
  T_ECSuite s
  left join T_ECUser u on (s.C_ParentGuid = u.C_GuidCode)

I drugi na bazie pierwszego, który prezentuje tylko komputery i notebook'i będące w użyciu

create view HardwareList_ComputersInUse] as
select *
  from HardwareList
  where
    Stan = 'w użyciu'
    and Typ in ('KOMPUTER', 'NOTEBOOK')

Utworzenie w Visual Studio 2010 projektu BDC Model

Po uruchomieniu VS2010 z szablonów SharePoint 2010 wybieramy BDC Model, następnie podajemy adres url serwera SharePoint i zaznaczamy Deploy as farm solution.
Visual Studio wybór typu projektu

Zdefiniowanie klasy przechowującej element listy

Zmieniamy nazwy utworzonych w projekcie klas Entity1.cs na Workstation.cs i Entity1Service.cs na WorkstationService.cs oraz ewentualnie innych, np. namespace'ów (ja u siebie tak zrobiłem) Klasa Workstation odpowiada za element listy i musi mieć zdefiniowane odpowiednie atrybuty. Dla zdefiniowanego przeze mnie widoku kod klasy przedstawia się następująco

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BdcDemo.BdcModelEwida
{
    /// <summary>
    /// This class contains the properties for Entity1. The properties keep the data for Entity1.
    /// If you want to rename the class, don't forget to rename the entity in the model xml as well.
    /// </summary>
    public partial class Workstation
    {
        public int KeyID { get; set; }
        public string NrEwid { get; set; }
        public string Producent { get; set; }
        public string Model { get; set; }
        public string Typ { get; set; }
        public string Sn { get; set; }
        public string Stan { get; set; }
        public string Nazwisko { get; set; }
        public string Imie { get; set; }
        public string Dzial { get; set; }
        public string Lokalizacja { get; set; }
        public string NrPokoju { get; set; }
        public string Stanowisko { get; set; }
        public string Telefon { get; set; }
        public string NetNazwa { get; set; }
    }
}

Zmiana w modelu BDC atrybutów zgodnie z wcześniej utworzoną klasą

Zgodnie ze zdefiniowaną klasą, trzeba w odpowiedni sposób zmienić utworzony przez kreatora model BDC.
Zmieniamy Entity1 na Workstation, jako identyfikator wybieramy KeyID (jest KONIECZNY unikalny identyfikator dla listy) i jego typ ustawiamy na System.Int32. Następnie zmieniamy i dodajemy nowe parametry dla modelu zgodnie z wcześniej zdefiniowanymi atrybutami klasy (Add Type Descriptor). Wykonać to należy dla obu metod ReadList oraz ReadItem.

Dla ReadItem jako zwracany parametr ustawiamy Workstation, natomiast dla ReadList WorkstationList (wg poniższych zrzutów ekranu)



Zaimplementowanie testowych metod ReadList, ReadItem w celu sprawdzenia rozwiązania.

Przystępujemy teraz do pracy na pliku WorkstationService.cs, modyfikując metody ReadList i ReadItem by dawały jakieś wartości bez komunikacji z bazą danych by sprawdzić tylko poprawność modelu i wdrażania rozwiązania do środowiska SharePoint. Utworzyłem dodatkowe prywatne metody do odczytu elementy i listy z przedrostkiem skeleton by uprościć testowanie i nie używać potem bloków zakomentowanego kodu. Poniżej pełny kod źródłowy klasy.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BdcDemo.BdcModelEwida
{
    /// <summary>
    /// All the methods for retrieving, updating and deleting data are implemented in this class file.
    /// The samples below show the finder and specific finder method for Workstation.
    /// </summary>
    public partial class WorkstationService
    {
        /// <summary>
        /// This is a sample specific finder method for Workstation.
        /// If you want to delete or rename the method think about changing the xml 
        /// in the BDC model file as well.
        /// </summary>
        /// <param name="id"></param>
        /// <returns>Workstation</returns>
        public static Workstation ReadItem(int id)
        {
            return (skeletonReadItem(id));
        }

        /// <summary>
        /// walkthrough skeleton
        /// - return example Worksation object
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private static Workstation skeletonReadItem(int id)
        {
            Workstation wk = new Workstation();

            wk.KeyID = 1;
            wk.NrEwid = "1234-PK";
            wk.Producent = "HP";
            wk.Model = "Model";
            wk.Typ = "Typ";
            wk.Sn = "Sn-1234";
            wk.Stan = "w uzyciu";
            wk.Nazwisko = "Nowak";
            wk.Imie = "Jan";
            wk.Dzial = "KA";
            wk.Lokalizacja = "But";
            wk.NrPokoju = "411";
            wk.Stanowisko = "referent";
            wk.Telefon = "14-14";
            wk.NetNazwa = "KA_REF";
            
            return (wk);
        }

        /// <summary>
        /// This is a sample finder method for Workstation.
        /// If you want to delete or rename the method think about changing the xml
        /// in the BDC model file as well.
        /// </summary>
        /// <returns>IEnumerable of Entities</returns>
        public static IEnumerable<Workstation> ReadList()
        {
            return (skeletonReadList());
        }

        /// <summary>
        /// walkthrough skeleton
        /// - add one element to list
        /// </summary>
        /// <returns></returns>
        private static IEnumerable<Workstation> skeletonReadList()
        {
            Workstation[] workstations = new Workstation[1];
            Workstation wk = new Workstation();
            wk.KeyID = 21743;
            wk.NrEwid = "pk-987";
            wk.Producent = "Dell";
            wk.Model = "Model";
            wk.Typ = "Typ";
            wk.Sn = "Sn-1234";
            wk.Stan = "w uzyciu";
            wk.Nazwisko = "Nowak";
            wk.Imie = "Jan";
            wk.Dzial = "KA";
            wk.Lokalizacja = "But";
            wk.NrPokoju = "411";
            wk.Stanowisko = "referent";
            wk.Telefon = "14-14";
            wk.NetNazwa = "KA_REF";

            workstations[0] = wk;

            return (workstations);
        }
    }
}

Zmodyfikowanie projektu do automatycznego deployment'u (dla Foundation)

W związku z tym, że w Foundation nie ma automatycznego wdrażania rozwiązania z poziomu Visual Studio 2010, skorzystałem z rozwiązania opisanego tutaj. Wymaga to pobrania kodu i dodanie Feature Event Receiver.

Jest jeszcze jedno, o wiele prostsze, lecz trzeba mieć zainstalowanego SharePointa (przynajmniej w wersji testowej) by dysponować plikiem Microsoft.Office.SharePoint.ClientExtensions.dll, opisane tutaj

Po tej operacji możliwe automatyczne wdrożenie rozwiązania dla SharePoint Foundation i model powinien być widoczny na liście, którą znajdziemy w Central Administration -> Application Management -> Manage service applications -> Business Data Connectivity Service

Konieczne jest jeszcze nadanie uprawnień do usługi BDC dla wszystkich zalogowanych użytkowników oraz rozszerzonych dla Administratora site'a.

Utworzenie nowej listy bazującej na BDC>

Końcowy etap to utworzenie listy przedstawiającej nasze dane.
W witrynie

  • dodajemy nową listę
  • wybieramy listę zewnętrzną
  • klikamy przycisk Utwórz
  • wprowadzamy jej nazwę np. "Lista sprzetu"
  • W polu Typ zawartośći zewnętrznej wybieramy utworzony wcześniej model [u mnie: BdcDemo.BdcModelEwida.Workstation (BdcModel1)]
  • Klikamy przycisk Utwórz
I w witrynie powinna być dostępna nowa lista zawierająca pola modelu i dane testowe, które zostały wcześniej określone w kodzie. Listę można oczywiście zmodyfikować jak inne do swoich potrzeb.

Zastąpienie metod testowych rzeczywistym odczytem danych

I to w zasadzie jest kompletny opis rozwiązania opartego na BDC Sernice. By urealnić dane przedstawiane w liście poniżej pełen kod klasy WorkstationService uzupełniony o komunikację z baza danych.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;

namespace BdcDemo.BdcModelEwida
{
    /// <summary>
    /// All the methods for retrieving, updating and deleting data are implemented in this class file.
    /// The samples below show the finder and specific finder method for Workstation.
    /// </summary>
    public partial class WorkstationService
    {
        static SqlConnection getSqlConnection()
        {
            string connStr = "Data Source=dbserver;User ID=user;Password=password; Initial Catalog=DBInventory";
            SqlConnection sqlConn = new SqlConnection(connStr);
            return (sqlConn);
        }

        /// <summary>
        /// This is a sample specific finder method for Workstation.
        /// If you want to delete or rename the method think about changing the xml 
        /// in the BDC model file as well.
        /// </summary>
        /// <param name="id"></param>
        /// <returns>Workstation</returns>
        public static Workstation ReadItem(int id)
        {
            // return (skeletonReadItem(id));
            return (sqlReadItem(id));
        }

        /// <summary>
        /// walkthrough skeleton
        /// - return example Worksation object
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private static Workstation skeletonReadItem(int id)
        {
            Workstation wk = new Workstation();

            wk.KeyID = 1;
            wk.NrEwid = "1234-PK";
            wk.Producent = "HP";
            wk.Model = "Model";
            wk.Typ = "Typ";
            wk.Sn = "Sn-1234";
            wk.Stan = "w uzyciu";
            wk.Nazwisko = "Nowak";
            wk.Imie = "Jan";
            wk.Dzial = "KA";
            wk.Lokalizacja = "But";
            wk.NrPokoju = "411";
            wk.Stanowisko = "referent";
            wk.Telefon = "14-14";
            wk.NetNazwa = "KA_REF";
            
            return (wk);
        }

        /// <summary>
        /// return Workstation object from database
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>        
        private static Workstation sqlReadItem(int id)
        {
            Workstation wk = new Workstation();
            SqlConnection sqlConn = getSqlConnection();
            sqlConn.Open();
            SqlCommand cmd = new SqlCommand();

            cmd.CommandText =
                "SELECT KeyID, NrEwid, Producent, Model, Typ, Sn, Stan, Nazwisko, Imie, " +
                " Dzial, Lokalizacja, NrPokoju, Stanowisko, Telefon, NetNazwa " +
                "FROM HardwareList_ComputersInUse " +
                "WHERE KeyID=" + id.ToString();
            cmd.Connection = sqlConn;

            SqlDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
            if (reader.Read())
            {
                wk.KeyID = reader.GetInt32(0);
                wk.NrEwid = reader.GetString(1);
                wk.Producent = reader.GetString(2);
                wk.Model = reader.GetString(3);
                wk.Typ = reader.GetString(4);
                wk.Sn = reader.GetString(5);
                wk.Stan = reader.GetString(6);
                wk.Nazwisko = reader.GetString(7);
                wk.Imie = reader.GetString(8);
                wk.Dzial = reader.GetString(9);
                wk.Lokalizacja = reader.GetString(10);
                wk.NrPokoju = reader.GetString(11);
                wk.Stanowisko = reader.GetString(12);
                wk.Telefon = reader.GetString(13);
                wk.NetNazwa = reader.GetString(14);
            }
            else
            {
                wk.KeyID = -1;
                wk.NrEwid = "Not found";
                wk.Producent = "";
            }
            reader.Close();
            sqlConn.Dispose();

            return (wk);
        }

        /// <summary>
        /// This is a sample finder method for Workstation.
        /// If you want to delete or rename the method think about changing the xml
        /// in the BDC model file as well.
        /// </summary>
        /// <returns>IEnumerable of Entities</returns>
        public static IEnumerable<Workstation> ReadList()
        {
            // return (skeletonReadList());
            return (sqlReadList());
        }

        /// <summary>
        /// walkthrough skeleton
        /// - add one element to list
        /// </summary>
        /// <returns></returns>
        private static IEnumerable<Workstation> skeletonReadList()
        {
            Workstation[] workstations = new Workstation[1];
            Workstation wk = new Workstation();
            wk.KeyID = 21743;
            wk.NrEwid = "pk-987";
            wk.Producent = "Dell";
            wk.Model = "Model";
            wk.Typ = "Typ";
            wk.Sn = "Sn-1234";
            wk.Stan = "w uzyciu";
            wk.Nazwisko = "Nowak";
            wk.Imie = "Jan";
            wk.Dzial = "KA";
            wk.Lokalizacja = "But";
            wk.NrPokoju = "411";
            wk.Stanowisko = "referent";
            wk.Telefon = "14-14";
            wk.NetNazwa = "KA_REF";

            workstations[0] = wk;

            return (workstations);
        }

        /// <summary>
        /// read list from real sql database
        /// </summary>
        /// <returns></returns>
        private static IEnumerable<Workstation> sqlReadList()
        {
            SqlConnection sqlConn = getSqlConnection();

            try
            {
                List<Workstation> allWorkstations = new List<Workstation>();
                sqlConn.Open();
                SqlCommand cmd = new SqlCommand();

                cmd.CommandText =
                    "SELECT KeyID, NrEwid, Producent, Model, Typ, Sn, Stan, Nazwisko, Imie, " +
                    " Dzial, Lokalizacja, NrPokoju, Stanowisko, Telefon, NetNazwa " +
                    "FROM HardwareList_ComputersInUse ORDER BY KeyID";
                cmd.Connection = sqlConn;

                SqlDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        Workstation wk = new Workstation();
                        wk.KeyID = reader.GetInt32(0);
                        wk.NrEwid = reader.GetString(1);
                        wk.Producent = reader.GetString(2);
                        wk.Model = reader.GetString(3);
                        wk.Typ = reader.GetString(4);
                        wk.Sn = reader.GetString(5);
                        wk.Stan = reader.GetString(6);
                        wk.Nazwisko = reader.GetString(7);
                        wk.Imie = reader.GetString(8);
                        wk.Dzial = reader.GetString(9);
                        wk.Lokalizacja = reader.GetString(10);
                        wk.NrPokoju = reader.GetString(11);
                        wk.Stanowisko = reader.GetString(12);
                        wk.Telefon = reader.GetString(13);
                        wk.NetNazwa = reader.GetString(14);
                        allWorkstations.Add(wk);
                    }
                }
                reader.Close();

                Workstation[] workstations = new Workstation[allWorkstations.Count];
                for (int i = 0; i < allWorkstations.Count; i++)
                    workstations[i] = allWorkstations[i];

                return (workstations);
            }
            catch (Exception e)
            {
                Workstation[] workstations = new Workstation[1];
                Workstation wk = new Workstation();
                wk.KeyID = -1;
                wk.Nazwisko = "Unable to retrieve data";
                wk.Producent = e.Message;
                workstations[0] = wk;

                return (workstations);
            }
            finally
            {
                sqlConn.Dispose();
            }
        }
    }
}

» Dodaj komentarz


Komentarze:

Produkty


Sharepoint RMS

  • rejestracja zgłoszeń serwisowych
  • przydzielanie zadań personelowi
  • aktualizacja statusu zlecenia
  • podgląd przez użytkownika stanu jego zgłoszeń
  • automatyczne informowanie email'em o stanie zlecenia
  • dowolna liczba instancji aplikacji
  • 5 webpart'ów
  • 4 szablony list
  • kompletny projekt w Visual Studio 2010

Artykuły

» więcej


Jeżeli któreś z przedstawionych przeze mnie rozwiązań okazało się wyjątkowo użyteczne możesz dokonać darowizny za pomocą Paypal. Możliwe, że to zdopinguje mnie do przedstawienia większej ilości tekstów i kodów źródłowych, które powstają podczas mojej codziennej pracy.