Tips and trick cu Entity Framework

 

1. Cum obtineti Connection String curat din Entity Framework Connection String

Sa zicem ca aveti definit connection string pentru EF in (web|app).config , ceva de genul :

<connectionStrings>
      <add name="iERPEntities" connectionString="metadata=res://*/ERP.csdl|res://*/ERP.ssdl|res://*/ERP.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=PC;Initial Catalog=ERP;Persist Security Info=True;User ID=x;Password=xy;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />

 

Si vreti sa preluati rezultatele de la o procedura stocata sau doar sa o executati, fara sa va mai chinuiti sa o treceti prin EF (mai mare deranjul). In consecinta va trebuie connection string-ul.

2. Cum faci Union – sau Join -  intre 2 IQueryable – ca sa iti dea macar una din ele, daca cealalta e null ?

3. Daca stii cheia unui obiect  -de obicei long ID  – cum obtii obiectul ?

4. Cum poti vedea ce genereaza, ca string sql, entitycontext – fara sa stai cu profiler-ul pe Sql Server ?

5. Daca vreti sa faceti o tabela pentru ca sa accesati/modificati continutul cu EF, ce este BestPractices de definit la ea ?

6. Cum validati un obiect in EF inainte de a salva ?

Va las sa va bateti capul! Raspunsurile mai jos…

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Rezolvarea 1.

string sqlc = "";
            using (ERPEntities e = new ERPEntities("name=iERPEntities"))
            {
                EntityConnection ec = e.Connection as EntityConnection;
                sqlc = ec.StoreConnection.ConnectionString;
            }

De ce e.Connection nu e direct EntityConnection si trebuie cast-uit, depaseste imaginatia mea …

Rezolvarea 2.

public static IQueryable<T> coalesceIntersect<T>(IQueryable<T> x, IQueryable<T> y)
           where T : class
        {

            if (x == null)
                return y;

            if (y == null)
                return x;

            return Queryable.Intersect<T>(x, y);

        }

Rezolvarea 3.

/// <summary>
        /// see also http://msdn.microsoft.com/en-us/library/bb896251.aspx
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="ID"></param>
        /// <param name="Include"></param>
        /// <returns></returns>
        public static T FindFromPrimaryKey<T>(this ObjectQuery<T> o, long ID, params string[] Include)
            where T : EntityObject
        {
            Type t = typeof(T);
            string FullPath = t.FullName;
            if (!KeysForObject.ContainsKey(FullPath))
            {
                lock (KeysForObject)
                {
                    if (!KeysForObject.ContainsKey(FullPath))
                    {
                        foreach(PropertyInfo pi in t.GetProperties())
                        {
                            object[] attr = pi.GetCustomAttributes(typeof(EdmScalarPropertyAttribute),false);
                            if(attr != null && attr.Length ==1)
                            {
                                EdmScalarPropertyAttribute a=attr[0] as EdmScalarPropertyAttribute;
                                if(a.EntityKeyProperty)
                                {
                                    KeysForObject.Add(FullPath,pi.Name);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
           

if(Include != null && Include.Length > 0)
            {
                foreach(string s in Include)
                {
                    o=o.Include(s);
                }
            }
return o.Where("it." + KeysForObject[FullPath] + " = " + ID).FirstOrDefault();

Rezolvarea 4.

http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=1555711&SiteID=1

Rezolvarea 5.

Definiti neaparat Primary Key ( eu de obicei pun un bigint identity )

Rezolvarea 6.

Vedeti http://msdn.microsoft.com/en-us/library/cc716714.aspx

Adaugati o clasa partiala de tipul entitatii in care puneti partial pe OnContextCreated ca sa interceptati SavingChanges

partial class Entities
    {

partial void OnContextCreated()
        {
       

            this.SavingChanges += new EventHandler(Entities_SavingChanges);
        }

}

Eu am facut apoi o interfata IValidate de felul urmator – simplist – :

public enum ISValid
    {
        Yes,
        No,
        SendDataContext
    }
    public interface IValidate
    {
        ISValid IsValidForSaving(ObjectStateEntry ose, out string mesaj);
    }
    public interface IValidateDataContext // daca am nevoie de verificari mai ample cu alt obiect …
    {
        bool IsValidForSavingDataContext(ObjectContext oc, ObjectStateEntry ose, out string mesaj);
    }

Apoi pe SavingChanges :

void Entities_SavingChanges(object sender, EventArgs e)
        {
                     Entities context = sender as Entities;
            foreach (ObjectStateEntry ose in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
            {
                if (ose.Entity == null)
                    continue;
                IValidate iv = ose.Entity as IValidate;
                if (iv != null)

{

string mesaj;
                   switch (iv.IsValidForSaving(ose, out mesaj))
                   {
                       case ISValid.No:
                           throw new NotValidException(ose.Entity.GetType().Name, mesaj);
                       case ISValid.Yes:
                           break;
                       case ISValid.SendDataContext:
                           IValidateDataContext ivDC = ose.Entity as IValidateDataContext;

                           if(!ivDC.IsValidForSavingDataContext(context,ose, out mesaj))
                               throw new NotValidException(ose.Entity.GetType().Name, mesaj);
                           break;
                   }

}

Ok, se putea si mai bine, cu IDataErrorInfo – dar … sa o lasam asa deocamdata

Leave a Reply

Your email address will not be published. Required fields are marked *