PDA

View Full Version : خواندن ویو از بانک و ست کردن مقادیر پراپرتی در کلاسهای یک به چند



resident
چهارشنبه 16 بهمن 1392, 20:19 عصر
سلام.

من یه جدول دارم به نام Person برای افراد و یه جدول برای ثبت تلفن ها به نام Contact. یه فرد می تونه چند تا تلفن داشته باشه.

یه View هم دارم که حاصل Join این دو تا جدوله.

در کلاس Person، یه Collection برای تعریف Contact ها تعریف کردم.

حالا مشکل من تو نسبت دادن مقادیر View به پراپرتی های Person و Contact است.

باید یه بار Person رو بخونم و پراپرتی هاشو ست کنم و یه بار هم این کار رو برای Contact کنم؟ یا راه دیگه ای هست؟

اینطوری تعداد مراجعمون به بانک زیاد میشه.
ممکنه نمونه کد بزارید؟


مرسی

Mahmoud.Afrad
پنج شنبه 17 بهمن 1392, 14:56 عصر
کد بزارید.

resident
پنج شنبه 17 بهمن 1392, 15:30 عصر
کد بزارید.

Person :

public int PersonID { get; set; }

public string Person_LastName { get; set; }

public string Person_FirstName { get; set; }

public string Person_FatherName { get; set; }

public List<CommonContact> Contacts { get; set; }


Contact:
public int PersonID { get; set; }

public int Contact_ContactTypeID { get; set; }

public string ContactType_Title { get; set; }

public int ProvinceID { get; set; }

public int? CityID { get; set; }

public int? ZoneID { get; set; }

public int Base_ContactTypeID { get; set; }



این از پراپرتی های کلاسهای Person و Contact.
تو SQL یه View دارم که جداول Person و Contact توش Join شدن.
حالا وقتی اطلاعات مورد نظر از View رو میخونم و با کد زیر اطلاعات Person رو میریزم تو Property هاش.


while (dbReader.Read())
{
var recordDictionary = new Dictionary<string, object>();

for (var fieldIndex = 0; fieldIndex < dbReader.FieldCount; fieldIndex++)
{
var fieldName = dbReader.GetName(fieldIndex);
var fieldValue = dbReader.GetValue(fieldIndex);

recordDictionary.Add(fieldName, fieldValue);
}
OnReceiveSelectEntity(recordDictionary, ResultCollection);// تو این متد، اطلاعات خونده شده از ویو به پراپرتی های کلاس فرد نسبت داده میشه.
}

یه موردی که این قسمت داره اینه که اگر یه فرد در ویو 3 رکورد داشته باشه، در این قسمت هم 3 بار خونده میشه ...
ولی نمیدونم بر ای خوندن Contact چه روشی بهتره.

Mahmoud.Afrad
پنج شنبه 17 بهمن 1392, 17:17 عصر
class Person
{
public int PersonID { get; set; }
public string Person_LastName { get; set; }
public string Person_FirstName { get; set; }
public string Person_FatherName { get; set; }
public List<Contact> Contacts { get; set; }
}

class Contact
{
public int PersonID { get; set; }
public int Contact_ContactTypeID { get; set; }
public string ContactType_Title { get; set; }
public int ProvinceID { get; set; }
public int? CityID { get; set; }
public int? ZoneID { get; set; }
public int Base_ContactTypeID { get; set; }
}


کوئری رو قرار ندادی.
باید کوئری رو بر حسب PersonId مرتب کنی و
با فرض اینکه پراپرتی ها هم نام ستون ها هست

List<Person> persons = new List<Person>();
Person p = null;
int prePersonId = -1;
while (dbReader.Read())
{
int currentPersonId = (int)dbReader["PersonID"];
if (prePersonId == -1 || prePersonId != currentPersonId)
{
p = new Person();
p.PersonID = currentPersonId;
p.Person_FirstName = Convert.ToString(dbReader["Person_FirstName"]);
p.Person_LastName = Convert.ToString(dbReader["Person_LastName"]);
p.Person_FatherName = Convert.ToString(dbReader["Person_FatherName"]);
persons.Add(p);
}

Contact c = new Contact();
c.PersonID = currentPersonId;
c.Contact_ContactTypeID = (int)dbReader["Contact_ContactTypeID"];
c.ContactType_Title = Convert.ToString(dbReader["ContactType_Title"]);
c.ProvinceID = (int)dbReader["ProvinceID"];
c.CityID = (int)dbReader["CityID"];
c.ZoneID = (int)dbReader["ZoneID"];
c.Base_ContactTypeID = (int)dbReader["Base_ContactTypeID"];

p.Contacts.Add(c);

prePersonId = currentPersonId;
}

PrePersonId آیدی نفر قبلی رو نگه میداره تا اگر با آیدی جدید فرق داشت یک Person جدید ایجاد بشه و به لیست اضافه بشه.
(کد تست نشده)

resident
پنج شنبه 17 بهمن 1392, 18:34 عصر
سپاسگزارم ازتون جناب Mahmoud.Afrad (http://barnamenevis.org/member.php?71297-Mahmoud.Afrad)
یه نکته ای هست. در این حالت مجبوریم همه ی اطلاعات رو بخونیم و ست کنیم حتی اگر نیازی نباشه.
به عنوان مثال حالت زیر رو فرض کنید:
فرض کنید در ویو برای Person، سی فیلد داریم و برای Contact، هشت فیلد. اما در سلکتی که زدیم 8 فیلد از Person و 5 فیلد از Contact مورد نیاز هست.
در این حالت باید 38 فیلد رو بخونیم .میخواستم با switch case اطلاعات فیلدهای موجود در سلکت رو بخونم و در پراپرتی ها قرار بدم اما انگار نمیشه. آیا روشی وجود داره ؟؟؟

Mahmoud.Afrad
پنج شنبه 17 بهمن 1392, 21:16 عصر
میتونی هر ستونی رو نیاز داری در سلکت قید کنی تا همون ها رو سلکت کنه نه همه رو.

ولی اگر خیلی اصرار داری اطلاعات رو در قالب کلاس های گفته شده در بیاری بهتره بری به سمت Entity Framework .

resident
پنج شنبه 17 بهمن 1392, 21:45 عصر
میتونی هر ستونی رو نیاز داری در سلکت قید کنی تا همون ها رو سلکت کنه نه همه رو.


اوکی . اگر طبق فرمایش شما ستونهای مورد نظر رو سلکت کنیم باز تاثیری روی کارمون نداره چون ما تو این روش داریم همه ی ستونهای ویو رو می خونیم و به پراپرتی ها نسبت میدیم...

Mahmoud.Afrad
پنج شنبه 17 بهمن 1392, 22:48 عصر
الان دقیقا سوالت چیه. کوئری رو هم بزاری بهتر میشه کمک کرد.

resident
جمعه 18 بهمن 1392, 12:27 عصر
الان دقیقا سوالت چیه. کوئری رو هم بزاری بهتر میشه کمک کرد.

ممنون که با صبوری ، سعی در مشکلات ما دارید...
این ویوی Person است.
توی برنامه ستونهایی که مورد نیاز هست رو در سلکت میارم نه همه ی ستونهای ویو رو.





create VIEW [personality].[Person_View]
AS
SELECT personality.Person.PersonID, personality.Person.FirstName AS Person_FirstName, personality.Person.LastName AS Person_LastName,
personality.Person.Sexular AS Person_Sexular, personality.Person.PrefixID AS Person_PrefixID,
personality.Person.FatherName AS Person_FatherName, personality.Person.BirthDate AS Person_BirthDate,
personality.Person.MarriageDate AS Person_MarriageDate, personality.Person.Psychology AS Person_Psychology,
personality.Person.ImagePath AS Person_ImagePath, personality.Person.NationalCode AS Person_NationalCode,
personality.PersonCompany.PersonCompanyID AS PersonCompany_PersonCompanyID,
personality.PersonCompany.AcquaintanceMethodID AS PersonCompany_AcquaintanceMethodID, personality.PersonCompany.Credit AS PersonCompany_Credit,
personality.PersonCompany.Description AS PersonCompany_Description, personality.PersonCompany.ConcurrencyVersion AS PersonCompany_ConcurrencyVersion,
personality.PersonCompany_Affiliation.AffiliationI D AS PersonCompany_Affiliation_AffiliationID,
personality.PersonCompany_Affiliation.PersonCompan yParentID AS PersonCompany_Affiliation_PersonCompanyParentID,
personality.PersonCompany_Affiliation.Description AS PersonCompany_Affiliation_Description, personality.Affiliation.Title AS Affiliation_Title,
personality.Contact.ContactID AS Contact_ContactID, personality.Contact.Title AS Contact_Title, personality.Contact.ContactTypeID AS Contact_ContactTypeID,
personality.Contact.Internal AS Contact_Internal, personality.Contact.Description AS Contact_Description, personality.Contact.CityID AS Contact_CityID,
personality.Contact.ZoneID AS Contact_ZoneID, personality.Province.Title AS Province_Title, personality.Province.ProvinceID AS Province_ProvinceID,
personality.City.Title AS City_Title, personality.City.CityCode AS City_CityCode,
personality.ContactType.Title AS ContactType_Title, personality.ContactType.BaseContactTypeID AS ContactType_BaseContactTypeID,
system.BaseContactType.Title AS BaseContactType_Title,
personality.PersonCompany_Ranking.RankingID AS PersonCompany_Ranking_RankingID, personality.Ranking.Title AS Ranking_Title,
personality.Ranking.Description AS Ranking_Description, personality.PersonCompany_User.UserID AS PersonCompany_User_UserID,
users.[User].LastName + N' ' + users.[User].FirstName AS User_FullName, users.[User].RoleID AS User_RoleID, users.[User].UserName AS User_UserName,
personality.PersonCompany_Affiliation.PersonCompan y_AffiliationID AS PersonCompany_Affiliation_PersonCompany_Affiliatio nID,
personality.PersonCompany_User.PersonCompany_UserI D AS PersonCompany_User_PersonCompany_UserID,
personality.PersonCompany_Ranking.PersonCompany_Ra nkingID AS PersonCompany_Ranking_PersonCompany_RankingID
FROM personality.Person INNER JOIN
personality.PersonCompany ON personality.PersonCompany.PersonCompanyID = personality.Person.PersonID INNER JOIN
personality.PersonCompany_Affiliation ON
personality.PersonCompany.PersonCompanyID = personality.PersonCompany_Affiliation.PersonCompan yChildID INNER JOIN
personality.Affiliation ON personality.PersonCompany_Affiliation.AffiliationI D = personality.Affiliation.AffiliationID LEFT OUTER JOIN
personality.Contact ON personality.PersonCompany.PersonCompanyID = personality.Contact.PersonCompanyID LEFT OUTER JOIN
personality.ContactType ON personality.ContactType.ContactTypeID = personality.Contact.ContactTypeID LEFT OUTER JOIN
[system].BaseContactType ON [system].BaseContactType.BaseContactTypeID = personality.ContactType.BaseContactTypeID LEFT OUTER JOIN
personality.City ON personality.Contact.CityID = personality.City.CityID LEFT OUTER JOIN
personality.Province ON personality.Province.ProvinceID = personality.City.ProvinceID LEFT OUTER JOIN
personality.PersonCompany_Ranking ON
personality.PersonCompany_Ranking.PersonCompanyID = personality.PersonCompany.PersonCompanyID LEFT OUTER JOIN
personality.Ranking ON personality.Ranking.RankingID = personality.PersonCompany_Ranking.RankingID LEFT OUTER JOIN
personality.PersonCompany_User ON personality.PersonCompany_User.PersonCompanyID = personality.PersonCompany.PersonCompanyID LEFT OUTER JOIN
users.[User] ON users.[User].UserID = personality.PersonCompany_User.UserID


جداول personality.PersonCompany_Ranking و personality.PersonCompany_User و personality.PersonCompany_Affiliation ارتباطشون با جدول Person مثل کانتکت است. یعنی یک Person می تونه چندین personality.PersonCompany_Ranking داشته باشه. می تونه چندین personality.PersonCompany_User داشته باشه و ...
حالا کلاس هامو یه مقدار کاملتر میذارم:








class Person
{
public int PersonID { get; set; }
public string Person_LastName { get; set; }
public string Person_FirstName { get; set; }
public string Person_FatherName { get; set; }

public List<Contact> Contacts { get; set; }
public List< PersonCompanyUser> Users{ get; set; }
public List< PersonCompanyRanking> Rankings { get; set; {
public List< PersonCompanyAffiliation> Affiliations { get; set; }
}

class Contact
{
public int PersonID { get; set; }
public int Contact_ContactTypeID { get; set; }
public string ContactType_Title { get; set; }
public int ProvinceID { get; set; }
public int? CityID { get; set; }
public int? ZoneID { get; set; }
public int Base_ContactTypeID { get; set; }
}
class PersonCompanyRanking
{
public Nullable<int> PersonID { get; set; }
public Nullable<int> RankingID { get; set; }

}
class PersonCompanyUser
{
public int PersonID { get; set; }
public int UserID { get; set; }
public string Description { get; set; }
}

حالا در مورد کدی که شما زحمت کشیدید و نوشتید 2 تا موضوع هست:
1. سوال مهمترم اینه که طبق کد شما هر بار که یه رکوردی رو از دیتاریدر میخونیم باید PersonID رو چک کنیم. اگر موجود نبود که Insert کنیم اما اگر موجود بود حالا باید ببینیم اطلاعات کدامیک از جداول Contact یا PersonCompanyRanking یا PersonCompanyUser جدید است . بعد تازه تو collection ای که اطلاعات مونو میریزیم PersonID مربوطه رو پیدا کنیم و اطلاعات این جداول رو به لیست Rankings و Users و .. اضافه کنیم. در حقیقت باید تشخیص بدیم که Contact یا PersonCompanyRanking یا PersonCompanyUser کدومشون جدیدن و به Person اضافه نشدن...

میخوام بدونم اینکار چطور انجام بشه بهتره؟


2. فرض کنید ویوی ما 50 تا فیلد داره. ولی ما اطلاعات 20 تا ستونش رو لازم داریم . تو سلکتی که از داخل برنامه میزینیم من اسم ستونهایی که لازم دارم رو تعیین می کنم. سلکت رو میزنم و همون اطلاعات رو از بانک میخونم . حالا میخوام بدونم آیا راهی وجود داره که در کدی که شما نوشتید به جای اینکه اطلاعات همه ی ستونها رو بخونیم و به پراپرتی های کلاس نسبت بدیم، فقط اونهایی که در سلکت تعیین کردیم رو بخونیم و به پراپرتی ها نسبت بدیم؟
s\

Mahmoud.Afrad
جمعه 18 بهمن 1392, 16:30 عصر
برای اضافه کردن کافیه آیدی اطلاعات جدید با آیدی قبلی مقایسه بشه و اگر متفاوت بود شئ جدیدی ایجاد بشه و به لیست اضافه بشه همونطور که برای person این کار رو انجام دادم میتونی برای دیگر کلاس ها هم همین کار رو انجام بدی. در ثانی با توجه به اینکه باید اطلاعات رو در کوئری مرتب کنی در اینصورت موقعی که داری از دیتاریدر اطلاعات میگیری مطمئن هستی که اطلاعات مربوطه به یک شخص پشت سر هم دریافت میشه. پس کوئری رو باید اصلاح کنی تا اطلاعات بر حسب personID مرتب بشه. در ضمن میتونی کوئری رو طوری اصلاح کنی که اطلاعات تکراری دریافت نشه.

در صورتی که فقط ستونهای مورد نیاز رو سلکت میکنی بدیهی هست که فقط همون ستون ها رو میتونی از دیتاریدر بخونی و به پراپرتی ها نسبت بدی.

اسکریپت جداول رو بزار تا من هم تست کنم.
روش کار کن ، چیز چندان سختی نیست.

resident
یک شنبه 20 بهمن 1392, 06:58 صبح
با توجه به اینکه باید اطلاعات رو در کوئری مرتب کنی در اینصورت موقعی که داری از دیتاریدر اطلاعات میگیری مطمئن هستی که اطلاعات مربوطه به یک شخص پشت سر هم دریافت میشه. پس کوئری رو باید اصلاح کنی تا اطلاعات بر حسب personID مرتب بشه. در ضمن میتونی کوئری رو طوری اصلاح کنی که اطلاعات تکراری دریافت نشه.

اما این اطلاعات قراره در گرید ویو نمایش داده بشه و اگر کاربر بخواد بر اساس فیلد دیگه ای غیر از PersonID اطلاعات رو مرتب کنه همه چیز بهم میریزه




اسکریپت جداول رو بزار تا من هم تست کنم.

چشم.... اتچ کردم

http://www.4shared.com/rar/x7-cr8Gcba/scripts.html