1397-10-19 21:50 یه پروژه ساده دفترچه تلفن نوشتم، مشکل با ثبت و لود عکس و تاریخ تولد مخاطب دارم
booysusa

 
درود

یه پروژه ساده دفترچه تلفن نوشتم، مشکل با ثبت و لود عکس و تاریخ تولد مخاطب دارم
به اینگونه که در ثبت عکس مخاطب و تاریخ تولد مخاطب در دیتابیس به خطا خوردم

داده عکس را از نوع varbinary گذاشتم و همچنین داده تاریخ رو از نوع DateTime قرار دادم
{ کلاس تاریخ میلادی به شمسی و بلعکس رو هم نوشتم}

قبل از اینکه این پست رو بزارم در نت گشتم و بیشتر مشکلاتم رو برطرف کردم، بجز این موارد که ذکر شد

این یک پروژه ساده هست، اگر امکانش هست اساتید محترم انجمن این پروژه رو دانلود و مشکلم رو برطرف کنن تا بتونم ادامش بدم
پیشاپیش بسیار سپاسگزارم


( در صورت امکان با همون کد نویسی ساده من پیش برید)
لینک دانلود
1397-10-21 20:54
حاجی شریفی
مؤسس سایت
 
سلام
برای تاریخ که دوتابع ساده ToPersianDateString و ToGeorgianDateTime خودتان پیدا کرده اید، پس کافی است به شکل زیر استفاده کنید:

//frmEditContact
//این خط را در بالای کد اضافه کنید
using Business.Extensions;

//سپس کد زیر را در بارگذاری تان اضافه کنید
mskDateOfBirth.Text = this.Contact.DateOfBirth.ToPersianDateString() ;

//و کد زیر را در تابع کلیک تان
mskDateOfBirth.Text = this.Contact.DateOfBirth.ToPersianDateString() ;



//frmNewContact
//مجدد این خط را در بالای کد اضافه کنید
using Business.Extensions;

//و این را هم در رویداد کلیک تان اضافه کنید
DateOfBirth = mskDateOfBirth.Text.ToGeorgianDateTime() ,


برای افزودن تصویر هم فیلدی به Contacts اضافه کنید و کد Insert و Update و دستور SQL و پارامترها را مانند بقیه موارد اصلاح کنید...

//Contacts.cs
//فیلد را اضافه کنید
public byte[] PicPerson { get; set; }

public bool Insert() { کد داخل تابع را مانند بقیه فیلدها اصلاح کنید }

public bool Update() { کد داخل تابع را مانند بقیه فیلدها اصلاح کنید }



//frmNewContact.cs
public partial class frmNewContact : Form
{
//به عنوان یک نوع راه حل ساده این فیلد را به فرم تان اضافه کنید
private byte[] m_BinaryImage;

private void btnSave_Click(object sender, EventArgs e)
{
Business.Entities.Contact contact = new Business.Entities.Contact()
{
FirstName = txtFirstName.Text,
LastName = txtLastName.Text,
DateOfBirth = mskDateOfBirth.Text.ToGeorgianDateTime() ,
Mobile = txtMobile.Text,
GroupType = bindingSourceGroupType.Current as Business.Entities.GroupType,
//و فیلد ذیتابیس را اینچنین پر کنید
PicPerson = this.m_BinaryImage
};
...
...
}

private void btnInsertPic_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "jpg Files |*.jpg|PNG Files |*.png" ;
if (openFileDialog1.ShowDialog(this) != DialogResult.OK) return;

this.pictureBox1.Image = new Bitmap(openFileDialog1.FileName);
//فیلد فرم را هم با این دستور پر کنید
this.m_BinaryImage = System.IO.File.ReadAllBytes(openFileDialog1.FileName);
}

موفق باشید.
1397-10-22 13:14
booysusa

 
جناب شریفی سپاسگزارم مثل همیشه عالی راهنمایی کردید و تاریخ شمسی کاملا درست در دیتابیس ثبت شد
فقط یک سوال برای ویرایش تاریخ:
من برای درج تاریخ این متد رو گذاشتم
public string PersianDate
{
get
{
return this.DateOfBirth.ToPersianDateString();
}
}

برای همین میتونستم در فرم هام فراخونیش کنم
ولی برای Set کردن ToGeorgianDateTime چطوری باید متدش رو بنویسم؟ که بتونم در فرم ها ازش استفاده کنم
الان من فقط میتونم یک داده رو Get کنم
متد Set کردن رو چطور باید بنویسم؟

این تیکه کد رو که در قسمت frmEditContact در دکمه ذخیره نوشتم خطا میده چون برای نمایش تاریخ هست نه ست کردن تاریخ
mskDateOfBirth.Text = this.Contact.DateOfBirth.ToPersianDateString();


امیدوارم مشکلم رو روشن تونسته باشم توضیح بدم
1397-10-22 13:44
booysusa

 
درود جناب شریفی عزیز، ببخشید در مورد عکس هم به دوتا مشکل برخوردم

در مورد درج عکس در دیتابیس:
سوال اول: من داده عکس رو از نوع varbinary در نظر گرفتم، وقتی private byte[] m_BinaryImage; میزنم خطا میده که از 100 کمتر هست و...
کد زیر برای داده از نوع varbinary درست هست؟
public byte[] PicPerson { get; set; }



سوال دوم: برای دکمهInsert این کد درست هست؟
var PicPersonParameters = new SqlCeParameter("@PicPerson", this.PicPerson);
1397-10-22 23:08
حاجی شریفی
مؤسس سایت
 
سلام
نقل قول نوشته شده توسط: booysusa
متد Set کردن رو چطور باید بنویسم؟

باید از متد برعکسش که ToGeorgianDateTime نام داشت و خودتان در پروژه دارید استفاده کنید.

شاید چیزی شبیه این
public string  PersianDate
{
get { return this .DateOfBirth.ToPersianDateString(); }
set { this .DateOfBirth = value .ToGeorgianDateTime(); }
}


البته میتوانید از کنترلرهایی شبیه این هم استفاده کنید که کار تبدیل را خودکار انجام میدهد:
http://support.h02.ir/fwlink/?LinkId=1002976157


نقل قول نوشته شده توسط: booysusa
وقتی private byte[] m_BinaryImage; میزنم خطا میده که از 100 کمتر هست

متوجه نمیشوم! متن دقیق خطا را قرار دهید.

نقل قول نوشته شده توسط: booysusa
برای دکمهInsert این کد درست هست؟

تقریبا...!
ولی در دستور SQL تان هم ، پارامتر مربوطه را اضافه کنید.

کدتان یکسری مشکلات ریز داشت...
مثلا یکجایی در Insert یا Update بود که یک پارامتر با یک نام مشخص را دو بار Add کرده بودید.
به این موارد هم دقت کنید.
شب خوش.
1397-10-23 20:02
booysusa

 
درود جناب شریفی عزیز
سپاسگزارم مشکل تاریخ برطرف شد

در مورد ذخیره عکس، هنگام زدن دکمه ثبت اطلاعات این خطا ظاهر میشود
Exception thrown: 'System.ArgumentNullException' in System.Data.SqlServerCe.dll ("Parameterized query expects a parameter value which was not supplied." )

و اینکه در پیام قبل گفته بودید این کد را به فرم اضافه کنم، در کجا و کدام فر؟
//فیلد فرم را هم با این دستور پر کنید

this.m_BinaryImage = System.IO.File.ReadAllBytes(openFileDialog1.FileName);


نقل قول
کدتان یکسری مشکلات ریز داشت...

مثلا یکجایی در Insert یا Update بود که یک پارامتر با یک نام مشخص را دو بار Add کرده بودید.

بله هنوز برای دستور آپدیت اقدام نکردم، گفتم اول Insert را تکمیل کنم سپس برای آپدیت اقدام کنم، (مواردی که فرمودید برطرف شد ولی هنوز برای آپدیت عکس اقدام نکردم، به این دلیل که هنوز در Insert عکس مشکل دارم)
1397-10-24 01:10
حاجی شریفی
مؤسس سایت
 
سلام
نقل قول نوشته شده توسط: booysusa
Parameterized query expects a parameter value which was not supplied
احتمالا تعداد پارامتر های داخل دستور SQL تان با تعداد پارامترهایی که Add کرده اید برابر نیست.
مثلا در دستور SQL آمده INSERT INTO ... @a..@b...@c ولی شما دویا چهار پارامتر را Add کرده اید.

نقل قول نوشته شده توسط: booysusa
و اینکه در پیام قبل گفته بودید این کد را به فرم اضافه کنم، در کجا و کدام فر؟
در فرم frmNewContact ورویداد btnInsertPic_Click
کد کامل تابع btnInsertPic_Click در پست دوم موجود است.
از همان کد copy/paste کنید.

موفق باشید.
1397-10-24 09:28
booysusa

 
درود بر شما
کدهای عکس رو کامل گذاشتم، الان این خطا رو میده
Exception thrown: 'System.InvalidOperationException' in System.Data.SqlServerCe.dll ("@PicPerson : Byte array truncation to a length of 100." )

همون خطایی که گفتم میگه طول 100 و...

هنگامی که به اینجا میرسه این خطا رو میده
myConnection.Open();

int result = myCommand.ExecuteNonQuery();  به این خط میره خطا میده

myConnection.Close();
1397-10-24 14:42
حاجی شریفی
مؤسس سایت
 
سلام
نقل قول نوشته شده توسط: booysusa
Byte array truncation to a length of 100

این خطا میگوید که فیلد دیتابیس شما فقط گنجایش 100 بایت را دارد.
یعنی در زمان ساخت دیتابیس فیلد مربوطه را varbinary(100) یا binary(100) گذاشته اید.

برای ذخیره تصویر (و درکل فایل) در SQL Server باید از فیلدها varbinary(max) استفاده کنید.
(دقیق یادم نیست) اگر در نسخه SQL Server Compact (که قدیمی تر است) نوع varbinary(max) را پیدا نکردید، از فیلد نوع image استفاده کنید.
نوع varbinary(max) و image یکی هستند و در SQL Server تا 2GB را میتوانند ذخیره کنند.

1397-10-25 21:51
booysusa

 
درسته جناب شریفی باید برای SqlCompact از گزینه image برای نوع داده دیتابیس استفاده کنم
مشکل ذخیره عکس با کمک شما برطرف شد، اکنون در حال دست و پنجه نرم کردن با نمایش عکس در دیتاگرید ویو هستم

من بخاطر اینکه آموزش ساخت دیتابیس SqlServer رو نمیدونستم رفتم سراغ SqlCompact، لینک آموزش نحوه ساخت دیتابی SqlServer هست بفرستید فرا بگیرم؟
1397-10-26 11:56
حاجی شریفی
مؤسس سایت
 
سلام
برای چیزی شبیه دفتر تلفن، همان SQL Server Compact و یا SQLite مناسب تر است.
سبک و کوچک هستند و نیاز به نصب ندارند والبته برنامه هم قرار نیست در شبکه کار کند.
(متاسفانه تولید نسخه Compact متوقف شده و در حال حاضر SQLite معروف ترین جایگزین در سطح برنامه های خیلی کوچک است که حتی در Xamarin و موبایل هم قابل استفاده است)

خود SQL Server در مقیاس متوسط تا بزرگ و صنعتی قابل استفاده است.
که نگارش های LocalDB و Express تا... Enterprise آن برای سطوح مختلف موجود است.

اگر هدف تان انجام یک پروژه دانشگاه است که برای پروژه تان همین Compact خوب است.
اگر کار نکرده اید و تصمیم به یادگیری هم دارید، پیشنهاد میکنم یک کتاب واقعی تهیه کنید.
مثلا:

راهنمای جامع SQL SERVER
ناشر: کانون نشر علوم
1397-10-26 12:48
booysusa

 
واقعا سپاسگزارم ازتون

سعی می کنم برم سمت SqlServer
1397-10-26 20:36
booysusa

 
ببخشید جناب حاجی شریفی من کانورت کردن عکس رو هرکاری میکنم نمیشه
میخوام در دیتاگرید ویوو نمایش بدمش

این تیکه کدش هست
public List<Contact> Read()
{
string command = "Select * from Contact";
var db = new DataAcsess.DatabaseManager();
var result = db.GetData(command);

var groupTypeList = new GroupType().Read();

List<Contact> lstResult = new List<Contact>();
foreach (DataRow r in result.Rows)
{
Contact contact = new Contact();
contact.ID = Convert.ToInt64(r["ID"]);
contact.FirstName = r["FirstName"].ToString();
contact.LastName = r["LastName"].ToString();
contact.DateOfBirth = Convert.ToDateTime(r["DateOfBirth"]);
contact.Mobile = r["Mobile"].ToString();
contact.PicPerson = (r["PicPerson"]; //در این قسمت خطا دارم، چطور باید تبدیلش کنم؟

//GroupType
GroupType groupType = new GroupType();
var groupTypeID = Convert.ToInt64(r["GroupTypeid"]);
contact.GroupType = groupTypeList.FirstOrDefault(a => a.ID == groupTypeID);

lstResult.Add(contact);
}
return lstResult;
}


1397-10-28 01:44
حاجی شریفی
مؤسس سایت
 
سلام
آن خط را میتوانید، شبیه این بنویسید:
contact.PicPerson = r["PicPerson"] as byte[];

از قالب ریزی پرانتزی هم میشود استفاده کرد ولی با کد فعلی اگر سلول DB-NULL باشد خطا میدهد، اما تبدیل AS این مشکل را ندارد.

مسئله دیگری که قابل ذکر است، عدم استفاده شما از یک ORM است.
اگر از یک ORM (مانند Entity Framework) در کدتان استفاده کنید، این ابزار کمک میکند تا SELECT/INSERT/UPDATE/DELETE-CRUD راحت تری داشته باشید.
مثلا همین حلقه for تان حذف میشود و خود EF میتواند مستقیم List<Contact> را برایتان بسازد.
در کل در پروژه های واقعی وجود یک ORM خیلی کمک میکند.
1397-11-01 16:59
booysusa

 
نقل قول
مسئله دیگری که قابل ذکر است، عدم استفاده شما از یک ORM است.
اگر از یک ORM (مانند Entity Framework) در کدتان استفاده کنید، این ابزار کمک میکند تا SELECT/INSERT/UPDATE/DELETE-CRUD راحت تری داشته باشید.
مثلا همین حلقه for تان حذف میشود و خود EF میتواند مستقیم List<Contact> را برایتان بسازد.
در کل در پروژه های واقعی وجود یک ORM خیلی کمک میکند.

سپاسگزارم بابت روشنگری
هنوز آموزش این مبحث رو شروع نکردم.

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

این دکمه ذخیره من هست، همه موارد درست ویرایش می شوند بجز عکس که نه لود میشود در کادرPictureBox و نه عکس جدید ذخیره میشود بجای عکس قبلی
//frmEditContact

private void frmEditContact_Load(object sender, EventArgs e)
{
// اینجا نمیدونم چطوری مثلا عکس پاس بدم به لود که ویرایشش کنه
// فکر میکنم باید در قسمت کدها در بخش اینتیتیس در کانتکس کدهای عکس را قرار بدم که متاسفانه بلد نیستم
DataRefreshGroupType();

cmbSelectGruop.SelectedValue = this.Contact.GroupType.ID;
txtFirstName.Text = this.Contact.FirstName;
txtLastName.Text = this.Contact.LastName;
mskDateOfBirth.Text = this.Contact.DateOfBirth.ToPersianDateString();
txtMobile.Text = this.Contact.Mobile;
Contact.PicPerson = this.m_BinaryImage;
}

private void btnSaveEdit_Click(object sender, EventArgs e)
{
Contact.GroupType = bindingSourceGroupType.Current as Business.Entities.GroupType;
Contact.FirstName = txtFirstName.Text;
Contact.LastName = txtLastName.Text;
Contact.DateOfBirth = mskDateOfBirth.Text.ToGeorgianDateTime();
Contact.Mobile = txtMobile.Text;
Contact.PicPerson = this.m_BinaryImage;

var result = Contact.Update();
if (result)
{
this.Close();
}
}
1397-11-02 02:38
حاجی شریفی
مؤسس سایت
 
سلام
برای بارگذاری تصویر می توانید از کدی شبیه این استفاده کنید.
اگر PictureBox1 که استفاده میکنید، میتواند از دفعات قبلی پر باقی بماند، بهتر است خط using در کدها باشد.
private void frmEditContact_Load(object sender, EventArgs e)
{
DataRefreshGroupType();

cmbSelectGruop.SelectedValue = this.Contact.GroupType.ID;
txtFirstName.Text = this.Contact.FirstName;
txtLastName.Text = this.Contact.LastName;
mskDateOfBirth.Text = this.Contact.DateOfBirth.ToPersianDateString();
txtMobile.Text = this.Contact.Mobile;

this.m_BinaryImage = Contact.PicPerson;


using (this.PictureBox1.Image) //old image dispose
this.PictureBox1.Image = ImageLoad(Contact.PicPerson);
}

private System.Drawing.Image ImageLoad(byte[] data)
{
if (data == null || data.Length <= 0) return null;
var mem = new System.IO.MemoryStream(data, 0, data.Length, false);
return System.Drawing.Image.FromStream(mem);
}
1397-11-03 19:39
booysusa

 
درود
آقای شریفی من کلی گشتم دیدم حرف شما درست هست و معمولا تصاویر را با ادرس آن در دیتابیس ذخیره می کنند نه خود فایل.
هرکاری کردم نشد ، امکانش هست شما برنامه را دانلود کنید و Insert - Update - Read رو بر اساس ذخیره عکس بصورت Location تنظیم کنید، به نحوی که یک پوشه کنار برنامه باشد برای عکس ها (البته دقیقا نمیدونم چجوری هست و بر اساس مطالعات خواندم که سناریو کار اینچنین هست) ( در نوشتن کدها مشکل دارم - ببخشید)
لینک دانلود
1397-11-05 19:46
booysusa

 
نقل قول
درود
آقای شریفی من کلی گشتم دیدم حرف شما درست هست و معمولا تصاویر را با ادرس آن در دیتابیس ذخیره می کنند نه خود فایل.
هرکاری کردم نشد ، امکانش هست شما برنامه را دانلود کنید و Insert - Update - Read رو بر اساس ذخیره عکس بصورت Location تنظیم کنید، به نحوی که یک پوشه کنار برنامه باشد برای عکس ها (البته دقیقا نمیدونم چجوری هست و بر اساس مطالعات خواندم که سناریو کار اینچنین هست) ( در نوشتن کدها مشکل دارم - ببخشید)
لینک دانلود


سپاسگزار میشم بررسی کنید
1397-11-05 20:11
حاجی شریفی
مؤسس سایت
 
سلام
میبخشید خیلی درگیر هستم و فرصت کمی دارم...

نقل قول نوشته شده توسط: booysusa
من کلی گشتم دیدم حرف شما درست هست و معمولا تصاویر را با ادرس آن در دیتابیس ذخیره می کنند

یادم نمی آید در این تاپیک در این مورد صحبتی کرده باشیم!
نگاه بسیار سریعی کردم و چند مورد را اصلاح کردم...
یک مورد عدم امکان ویرایش تصویر بود و مشکل دیگر عدم امکان درج/ثبت یک فرد بدون تصویر بود.
هر دومورد فوق را با همان کد وشیوه قبلی خودتان اصلاح کردم.
الان یک امتحانی کنید:
booysusa-Test23.zip

==============

اما بحث ذخیره تصویر درون دیتابیس یا ذخیره آن در سیستم فایل، یک بحث بسیار قدیمی و دامنه دار است که از جنبه های مختلف قابل بررسی است و هر کدام طرفداران و مخالفان خاص خود را دارد.

ذخیره همینطوری و مستقیم فایل در کنار برنامه هم مشکلات خاص خود را دارد که الان فرصت بررسی این مشکلات وجود ندارد.

در شرکت قبلی که بودم برای پروژه ای با ذخیره سازی فایل ها در سطح چند صد ترابایت از کتابخانه زیر استفاده کردیم:
Diamond.FileStorage

ولی برای شما که فعلا پروژه تان را تا اینجا رسانده اید، گمانم مشکلات پروژه خودتان را حل کنید بهتر است تا کل سیستم کاری پروژه تان را عوض کنید.
حالا آزمایشی روی سورس جدیدتان انجام دهید، تست کنید و ببینید چه مشکلات دیگری دارد، اگر پیدا کردید و نتوانستید حل کنید، مطرح کنید تا حلش کنیم.
شب خوش.
1397-11-05 21:59
booysusa

 
ببخشید بین کارهاتون مدام سوال میپرسم
واقعا سپاسگزارم از شما جناب شریفی
بسیار عالی دقیقا همین رو میخواستم

چندتایی مشکل داشت که تو این مدتی که شما روی کارتون تمرکز داشتید، من مشکلاتش رو برطرف کردم، مثلا جستجو کردن و چندتا اشکال ریز و درشت دیگه

فقط یه نکته: من میبینم شما هرباری که کد را ویرایش می کنید، دیتابیس را بصورت اتچ شده میزارید کنار برنامه، خاصیت این کار چی هست و اینکه من چطور اینکارو کنم؟
و نکته دوم ا ینکه من یه فرم جدید اضافه کردم که بتونم اطلاعات مخاطب رو مشاهده کنم (یه چیزی شبیه به همون فرم ویرایش با این تفاوت که امکان ویرایش دیگه نیست و فقط میتونم ببینم اطلاعات رو) روی این فرم جدید یه دکمه گذاشتم که با زدن اون بتونم عکس مخاطب رو روی دسکتاپ یا هرجای دیگه ذخیره کنم (امکانش هست کد پشت این باتوم رو بنویسید) ببخشید بازم، دیگه در حال به پایان رسوندن این پروژم هستم