Planning Step 3: Determine the Identifiers for Each Entity

Applies to: SharePoint Server 2010

For each external content type, you must identify the fields that uniquely identify an instance of that external content type. Without an identifier, the Business Data Connectivity (BDC) service cannot uniquely identify an entity instance. The data returned by a back-end application method is just a blob of data without identifiers. Only if the returned data also has identifiers can the data have semantic meaning in the BDC, and only then can you implement actions for the entities, search on the entities, and crawl the entities.

For example, the Customer class in the SampleWebService proxy contains a field named CustomerID that uniquely identifies a customer instance. Therefore, CustomerID can be used as the identifier for the Customer external content type. The following is the Customer class definition from the Web Service proxy.

public partial class Customer {
    
    private string customerIDField;
    
    private string nameField;
    
    private System.Nullable<long> workPhoneNumberField;
    
    private System.Nullable<long> mobilePhoneNumberField;
    
    private string industryField;
    
    private string webSiteField;
    
    private CustomerAddress[] customerAddressesField;
    
    private string parentCustomerIDField;
    
    /// <remarks/>
    public string CustomerID {        get {            return this.customerIDField;        }        set {            this.customerIDField = value;        }
    }
    
    /// <remarks/>
    public string Name {
        get {
            return this.nameField;
        }
        set {
            this.nameField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
    public System.Nullable<long> WorkPhoneNumber {
        get {
            return this.workPhoneNumberField;
        }
        set {
            this.workPhoneNumberField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
    public System.Nullable<long> MobilePhoneNumber {
        get {
            return this.mobilePhoneNumberField;
        }
        set {
            this.mobilePhoneNumberField = value;
        }
    }
    
    /// <remarks/>
    public string Industry {
        get {
            return this.industryField;
        }
        set {
            this.industryField = value;
        }
    }
    
    /// <remarks/>
    public string WebSite {
        get {
            return this.webSiteField;
        }
        set {
            this.webSiteField = value;
        }
    }
    
    /// <remarks/>
    public CustomerAddress[] CustomerAddresses {
        get {
            return this.customerAddressesField;
        }
        set {
            this.customerAddressesField = value;
        }
    }
    
    /// <remarks/>
    public string ParentCustomerID {
        get {
            return this.parentCustomerIDField;
        }
        set {
            this.parentCustomerIDField = value;
        }
    }
}
    public Customer(string id, string name, uint? workphone, uint? mobilephone, string industry, string website, CustomerAddress[] custaddresses, string parentid)
    {
        this.CustomerID = id;
        this.Name = name;
        this.WorkPhoneNumber = workphone;
        this.MobilePhoneNumber=mobilephone;
        this.Industry = industry;
        this.WebSite = website;
        this.CustomerAddresses = custaddresses;
        this.ParentCustomerID = parentid;
    }
}

However, for the LineItem class, OrderID and ProductID together make a LineItem instance. Therefore, you declare OrderID and ProductID as identifiers for the LineItem external content type, as shown in the following code example.

public partial class LineItem {
    
    private string orderIDField;
    
    private string productIDField;
    
    private string productNameField;
    
    private int orderQtyField;
    
    private decimal unitPriceField;
    
    private decimal lineTotalField;
    
    /// <remarks/>
    public string OrderID {        get {            return this.orderIDField;        }        set {            this.orderIDField = value;        }    }
    
    /// <remarks/>
    public string ProductID {        get {            return this.productIDField;        }        set {            this.productIDField = value;        }    }
    
    /// <remarks/>
    public string ProductName {
        get {
            return this.productNameField;
        }
        set {
            this.productNameField = value;
        }
    }
    
    /// <remarks/>
    public int OrderQty {
        get {
            return this.orderQtyField;
        }
        set {
            this.orderQtyField = value;
        }
    }
    
    /// <remarks/>
    public decimal UnitPrice {
        get {
            return this.unitPriceField;
        }
        set {
            this.unitPriceField = value;
        }
    }
    
    /// <remarks/>
    public decimal LineTotal {
        get {
            return this.lineTotalField;
        }
        set {
            this.lineTotalField = value;
        }
    }
}

However, there might be cases where a certain external content type does not need an identifier, for example, the Address external content type in the SampleWebService proxy. The Address external content type does not have an identifier, as we just want to display a list of addresses for a customer. This means that it's just a blob of data; you cannot run actions on this external content type, use the external content type instance picker, relate with the external content type, search on or crawl the external content type, and so on.

public partial class CustomerAddress {
    
    private CustomerStreet streetField;
    
    private string cityField;
    
    private States stateProvinceField;
    
    private string countryRegionField;
    
    private string postalCodeField;
    
    /// <remarks/>
    public CustomerStreet Street {
        get {
            return this.streetField;
        }
        set {
            this.streetField = value;
        }
    }
    
    /// <remarks/>
    public string City {
        get {
            return this.cityField;
        }
        set {
            this.cityField = value;
        }
    }
    
    /// <remarks/>
    public States StateProvince {
        get {
            return this.stateProvinceField;
        }
        set {
            this.stateProvinceField = value;
        }
    }
    
    /// <remarks/>
    public string CountryRegion {
        get {
            return this.countryRegionField;
        }
        set {
            this.countryRegionField = value;
        }
    }
    
    /// <remarks/>
    public string PostalCode {
        get {
            return this.postalCodeField;
        }
        set {
            this.postalCodeField = value;
        }
    }
}

Next Steps

Planning Step 4: Identify the Filters Required for Each Entity