반응형

안녕하세요. 애드소프트 입니다.

Visual studio를 주로 사용하면서 마이크로소프트 솔루션을 많이 이용하여 연동하는데

특별한 공을 들이는 경우가 적었습니다.

이번에 개인적으로 웹사이트를 개발할려고 하다보니 상용 RDBMS인 MSSQL이 설치비와 유지비가 

생각보다 많다고 느껴 오픈 RDBMS를 찾다가 MariaDB를 사용해 보게되었습니다.

 

연동이 어려운것은 아니지만 시행 착오를 격게되어 다른 분들도 생각하고 계시다면

도움이 될거 같아 포스팅해 봅니다.

 

Microsoft에서 제공하는 Entity Framework에 Code First라는 기능을 제공하는데요.

다 아시겠지만 이기능을 이용하면 DB를 수동으로 작성하지 않아도 자동으로 Scheme랑 Data부분을 

등록 수정 할 수 있답니다.

 

서두가 길었습니다.

간단하게 사용방법을 알아보도록 하겠습니다.

처음 접하는 분이시라면 Microsoft Docs에 잘 설명되어 있으니 한번 사용해 보세요.

새 데이터베이스에 Code First-EF6 | Microsoft Docs

 

새 데이터베이스에 Code First-EF6

Entity Framework 6에서 새 데이터베이스에 Code First

docs.microsoft.com

프로젝트 생성 

새로운 프로젝트를 만들도록 하겠습니다.

Visual Studio 2019 기준입니다. 참고하세요^^

Visual Studio를 실행하여 "새 프로젝트 만들기(N)" 메뉴를 선택합니다.

프로젝트 형식에서 웹을 선택하거나 검색을 이용하여 다음 항목을 찾아 프로젝트를 생성하여 줍니다.

 

프로젝트 명을 입력하고 프로젝트가 생성될 경로를 설정하도 만들기 버튼을 눌러줍니다.

 

MVC를 이용하기 때문에 MVC를 선택했고 인증을 이용하기 위해 인증부분을 SQL를 이용하도록 선택하였습니다.

외부인증도 제공하니 개별사용자인증을 이용하도록 하겠습니다.

프로젝트가 생성되었습니다.

 

Code First를 이용하기 위해 DB를 설치해야합니다.

Download MariaDB Products & Tools | MariaDB

 

Download MariaDB Products & Tools | MariaDB

Download the latest versions of MariaDB Platform, MariaDB Community Server, Cloud Database (SkySQL), ColumnStore and MaxScale.

mariadb.com

위 사이트에서 MariaDB Community Server를 다운받아 설치하면 됩니다.

추가로 Connector도 하나 설치해 주세요. 다음 경로에서 다운받아 설치하시면 됩니다.

MySQL :: Download Connector/NET

 

MySQL :: Download Connector/NET

MySQL Connector/NET 8.0 is highly recommended for use with MySQL Server 8.0, 5.7 and 5.6. Please upgrade to MySQL Connector/NET 8.0.

dev.mysql.com

설치 방법은 시간상 생략하도록 하겠습니다.

 

 

마지막으로 Nuget Packeage 관리자를 이용하여 "Mysql.Data.Entity"를 찾아 설치해 줍니다.

 

시간이 걸리니 잠시 기다려 주세요. 설치가 시작되면 다음과 같이 팝업창을 보실 수 있습니다.

확인을 눌러주세요

설치는 모두 완료 되었습니다. 설정부분을 보도록 하겠습니다.

 

설치가 완료되었다면 솔루션 탐색기 상의 Web.config 내용을 살펴 봅시다.

 

  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-CodeFirstForMariaDB-20210324111441.mdf;Initial Catalog=aspnet-CodeFirstForMariaDB-20210324111441;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  
  ...
  
      <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>

위 내용으로 기본 설정되어 있는데 이부분을 MariaDB로 설정을 변경해야 합니다.

MariaDB는 MySQL이 Oracle로 상용화 되면서 파생된 오픈 소스로 알고 있는데 자세한 내용은 구글을 이용하시면 좋을거 같아요. 이 말씀을 드리는 이유는 설정시에 MySQL이라는 이름을 자주 보게 될 것입니다.

 

Models 폴더의 IdentityModels의  내용과 비교해보면 연동관계를 아실 수 있습니다.

 

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }

 

web.config에 등록된 DefaultConnection에 설정된 DB연동 정보와 IdentityModels의 DefaultConnection의 Scheme가 연동되는것을 알 수 있습니다.

 

web.config의 다음 부분을 

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-CodeFirstForMariaDB-20210324111441.mdf;Initial Catalog=aspnet-CodeFirstForMariaDB-20210324111441;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

  ...

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

다음과 같이 수정해 줍니다.

  <connectionStrings>
    <add name="DefaultConnection" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;userid={사용자ID};password={패스워드};database={기본DB};persistsecurityinfo=True" />
  </connectionStrings>  
  
  ...
  
   <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.10.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </providers>
  </entityFramework>

 

중요한 것은 connection string의 name 부분과 model의 base에 들어 있는 DefaultConnection이 일치해야합니다.

Models - IdentityModels.cs 파일을 다음과 같이 수정합니다.

 

using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
//add using
using MySql.Data.Entity;

namespace CodeFirstForMariaDB.Models
{
    // ApplicationUser 클래스에 더 많은 속성을 추가하여 사용자의 프로필 데이터를 추가할 수 있습니다. 자세한 내용은 https://go.microsoft.com/fwlink/?LinkID=317594를 참조하세요.
    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // authenticationType은 CookieAuthenticationOptions.AuthenticationType에 정의된 항목과 일치해야 합니다.
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // 여기에 사용자 지정 사용자 클레임 추가
            return userIdentity;
        }
    }

    //add type
    [DbConfigurationType(typeof(MySqlEFConfiguration))]
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }
}

 

 

설정 후 패키지 관리자 콘솔을 열어 줍니다. "도구-Nuget 패키지 관리자" 에서 찾을 수 있습니다.

패키지 관리자 명령창에 다음 명령을 입력합니다.

오류가 나서 찾아 봤더니 MySqlConnector가 참조로 등록되지 않아 발생하는 오류이네요.

경로 찾기도 귀찮으니 nuget 패키지로 설치 하도록 하겠습니다.

 

패키지 관리자에 다음 명령어를 입력합니다.

 

Install-Package MySqlConnector

 

설치가 완료되면 다시 Enable-Migragions -Force 를 실행합니다.

Code First가 설정된것을 확인 하실 수 있습니다.

Update-Database 명령을 이용하여 기본 테이블을 업데이트 합니다.

 

이런 오류가 발생한다면 다음과 같이 조치하세요.

Migrations 폴더의 IdentityModels.cs 파일입니다.

        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }

 

다시 명령을 실행해 보시면 다음과 같은 결과를 보실 수 있습니다.

 

DB를 확인해보겠습니다.

기본적인 테이블이 생성되었습니다.

 

시간상 사용법은 다음기회에  포스팅하기로 하겠습니다.

 

감사합니다.

반응형
반응형

우리신랑과 시어머니는 회를 좋아한다.

나도 회를 좋아하는 편이지만, 위의 두분에 비하면 많이 좋아하지 않는다.

그래서 횟집을 가면 회도 먹지만 회에서 나오는 스끼다시를 더 많이 먹는 편이다.

그래서 처음 이사해서 회를 먹으러 가던곳은 창천동에 있는 동해바다수산이었다.

헌데 그곳은 시내에 있어서 주차하기가 너무 힘들다.

그리고 회를 좋아하는 두분은 생각보다 회를 많이 못먹는다. ^^;;

그후 분수대 오거리에 있는 광어한마리라는 곳이다.

이곳의 회도 신선하고 가격도 저렴해서 자주 찾아갔었다.

이곳도 마찬가지로 시내에 있어서

백사면에 사는 우리는 차를 끌고 가면..

주차하기가 힘들어서 애를 먹었다.

한동안 회를 먹지 않다가 발견한 곳이 바로 이곳이다.

출처 - 네이버 지도

이곳은 증포사거리에서 송정동쪽으로 가다보면 나오는 곳이다.

위의 캡쳐 사진과 같이..

주차장이 참 넓다.

그래서 차를 가지고 가도 주차에는 아무 어려움이 없었다.

우선 주차에서 어려움이 없어

편하게 진입할 수 있었다.

건물 1층을 다 쓰는거인지..

들어가보니 내부도 생각보다 넓었다.

그리고 코로나때문일지는 모르지만

앉아있는 손님들을 보니.. 좌석을 꼭!!! 띄어서 앉게 하시더라.

손님1

빈테이블

빈테이블

손님2

손님3

빈테이블

위의 표같이 앉게 하시는데..

사실 우리도 먹으러 간것이지만... 저렇게 띄엄띄엄 앉게 하기란 참으로 어렵다.

그런데도.. 손님들을 그렇게 앉게 하시는데.. 맘이 놓이더라.

우리는 손님4자리에.. 앉았다.

손님1

 

빈테이블

손님2

 

 

 

 

손님3

 

빈테이블

손님4 

손님이라고 적혀 있는 곳에만 손님을 앉게 하시더라

우리가 왔을때는 손님1에만 사람이 있었고,

우리가 손님4자리에 그 다음 손님을 손님2자리에..

그 다음 손님을 손님3에..

근데 손님3에 앉으시려는 분들이 다른 자리에 가려고 하니

자리가 없어서 안된다고 하더라.

그분들은 방금 다른분이 나가신 자리에 앉는다고 다른 자리로 옮겼지만,

방금 나가신 분들이 없었다면 못앉고 가야할 수도 있었다는 말이다.

쉽지 않을 것 같다. 내가 사장이면... 물론 코로나 방역지침을 어기면..

제약도 많아지고 하겠지만, 그런거 따지는 분이 아니라면..

불법(?)으로 할 수도 있는 것을..

안하시는 것 같아서 맘 편히 먹을 수 있었다.

자리에 앉은 우리는

어떤걸 먹을까?? 생각하다..

동해바다 세트라는 것이 있어 물어보았다.

메뉴에는 스끼다시내용만 보여서.. 물어보니 회도 나온다고 하더라..

(당연한건가?? ^^;;)

1인당 4만원

우리 아들까지 4명이기에 비쌀수도 있고 안비쌀수도 있지만,

한번 시켜보았다.

울아덜은...ㅋㅋ 속이 조금 안좋은지 자기는 회를 안먹겠다고 해서

동해바다세트 3개를 시켰다.

우선 튀김, 생선2개, 가자미찜조금, 옥수수, 연어샐러드, 회무침이 조금씩 나왔다.

앗.. 전복죽과 알밥도 주셨다.

그리고 새우장도 주셨다..ㅋㅋㅋㅋ

새우익힌건 먹으면 탈나는데.. 새우장은 잘 먹기에..좋았다.ㅋ

스끼다시가 이게 끝인가?? 하면서 먹는데..

소라, 전복, 굴, 낙지, 피조개, 멍게, 해삼 등이 나왔다.

그리고 소고기 초밥도 나왔다. ㅋㅋ

 

 

 

장사가 잘 되어서 그런지 해산물들이 신선하고 맛있었다.

울 신랑은 멍게를 먹지 않는데..

이건 비린내도 안나고 맛있다고 하더라.

왜 먹지 않냐고 물어보니..

옛날에 회를 먹으러 횟집에 갔는데..

스끼다시로 나온 멍게와 해삼을 먹어보고.

너무 비려서 그 후로는 안먹는다고 하더라.

근데 여긴 비리지도 않고 맛있다고 했다.

그래서 나도 해삼을 먹어봤다.

.

.

.

맛있더라~~ㅋㅋ

맛있게 스끼다시를 먹다보니

배가 부르더라..^^;;

드디어 회가 나왔다.

오른쪽부터

농어, 참돔, 광어, 우럭순으로 회가 나왔다.

(광어랑 우럭이 맞는지 잘 모르겠다.

나는 이미 배가 불렀다~~ ㅋㅋ)

참돔이 맛있더라..

다른건.. 그냥 회일뿐이라서..^^;; 잘 모르겠다.

그래도 맛있게 먹는 식구들을 보니 좋더라

울아덜도..

입맛이 없어요~~에서..

잘먹더라...^^;;

다들 배가 부르지만~~

울신랑이 마시던 술이 남아서.

매운탕을 시켜서 먹었다.

사진은 없는데..

그걸로..또..국물 떠먹고 있는 내모습이 순간 보이더라..ㅋㅋ

다덜 매운탕 나오기전에..

배부르다고 했는데..

다덜 잘 먹더라~~!! ㅋㅋㅋㅋㅋ

가격은 광어한마리에서 먹던것보다는 더 나왔지만,

각자 더 맛있는거 먹으면서 행복하게 먹은 것 같아

기분이 너무 좋았다~~~ ^^

반응형
반응형

오늘 뉴스를 보는데.. 비트코인 이야기가 나오더라.

내가 아는 지인은 예전에 비트코인을 샀다가 크게 손해를 봤었다.

좋은것 같지만 나에게 나가오는 느낌의 비트코인은... 좀.... 그렇다.

그래서 기사를 읽는데...

오~~ 테슬라의 한마디에 비트코인이.. 4만 4000달러(약 4932만원)을 돌파했다고 한다.

비트코인만 본다면 상당히 매력있는 화폐이다.

어쩌면 우리가 지금 쓰는 화폐도 종이가 있을 뿐이지 그저 가상화폐랑 다르지 않다고 본다.

근데.. 나는 아직까지는 불안하다.

내가 테슬라처럼 선두주자가 되지 못하는 이유는.. 아마도 그걸 사고 난 후..

가격이 그때그때 틀려지는 것을 불안해서 보기 어려워서 그러는건 아닐까 한다.

우리가 사용하는 지폐처럼 믿을수 있다면.. 아주 좋은 화폐일 수도 있다.

통화란 믿음이 있어야지.. 가치가 있는 것 같다.

지금 울집 밖에 있는 돌에게 천원의 가치가 있어!!! 라고 말해봤자

누가 그걸 천원의 가치가 있는 돌이라고 봐줄까?

재력이 있는 사람들은 그 돌을 가져오면 천원을 줄꺼니깐 돌을 나에게 가져와라~~

라고 한다면 그 돌은 천원의 가치를 갖게 되지만, 천원을 주지 못하면 그건 그저 길바닥에 있는 돌일뿐이다.

나도 선두주자가 되고싶다..

 

 

테슬라 “비트코인 1조원 넘게 투자”...이 말에 비트코인 4932만원 돌파

테슬라가 15억 달러(약 1조 6815억원) 어치의 비트코인을 매입했다고 미 CNBC방송, 블룸버그 통신 등이 8일(현지 시각) 보도했다. 외신에 따르면, 테슬라는 이날 이 같은 내용이 담긴 자료를 미국증

news.naver.com

 

반응형
반응형

 

개요

스피너는 값 집합에서 하나의 값을 선택할 수 있는 빠른 방법을 제공합니다. 기본 상태의 스피너는 현재 선택된 값을 표시합니다. 스피너를 터치하면 기타 모든 사용 가능한 값을 포함하는 드롭다운 메뉴가 표시되며, 여기서 새 값을 선택할 수 있습니다.

Spinner 객체를 사용하여 레이아웃에 스피너를 추가할 수 있습니다. 이 작업은 일반적으로 XML 레이아웃에서 <Spinner> 요소를 사용하여 실행해야 합니다. 예:

 

<Spinner
    android:id="@+id/planets_spinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

 

선택 항목 목록으로 스피너를 채우려면 Activity 또는 Fragment 소스 코드에 SpinnerAdapter를 지정해야 합니다.

주요 클래스는 다음과 같습니다.

사용자 선택 항목으로 스피너 채우기

스피너에 제공하는 선택 항목은 어떠한 소스에서든 가져올 수 있지만, SpinnerAdapter를 통해 제공되어야 합니다. 예를 들어 선택 항목을 배열에서 사용할 수 있는 경우에는 ArrayAdapter, 선택 항목을 데이터베이스 쿼리에서 사용할 수 있는 경우에는 CursorAdapter를 통해 제공합니다.

예를 들어, 스피너에 사용할 수 있는 선택 항목이 사전 결정된 경우에는 문자열 리소스 파일에 정의된 문자열 배열을 사용하여 이러한 선택 항목을 제공할 수 있습니다.

 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="planets_array">
        <item>Mercury</item>
        <item>Venus</item>
        <item>Earth</item>
        <item>Mars</item>
        <item>Jupiter</item>
        <item>Saturn</item>
        <item>Uranus</item>
        <item>Neptune</item>
    </string-array>
</resources>

이러한 배열과 함께 Activity 또는 Fragment에 다음 코드를 사용하여 ArrayAdapter의 인스턴스를 통해 스피너에 이러한 배열을 제공할 수 있습니다.

 

createFromResource() 메서드를 사용하면 문자열 배열에서 ArrayAdapter를 생성할 수 있습니다. 이 메서드의 세 번째 인수는 선택된 항목이 스피너 컨트롤에 나타나는 방식을 정의하는 레이아웃 리소스입니다. simple_spinner_item 레이아웃은 플랫폼에서 제공하며 스피너의 모양에 관해 자체적인 레이아웃을 직접 정의하고자 하지 않을 경우 사용해야 하는 기본 레이아웃입니다.

그런 다음, setDropDownViewResource(int)를 호출하여 어댑터가 스피너 선택 항목의 목록을 표시하는 데 사용해야 하는 레이아웃을 지정해야 합니다(simple_spinner_dropdown_item은 플랫폼에서 정의하는 또 다른 표준 레이아웃임).

setAdapter()를 호출하여 어댑터를 Spinner에 적용합니다.

 

사용자 선택에 응답

사용자가 드롭다운에서 항목을 선택하면 Spinner 객체가 항목 선택 시 이벤트를 수신합니다.

스피너에 관한 선택 이벤트 핸들러를 정의하려면 AdapterView.OnItemSelectedListener 인터페이스와 이에 상응하는 onItemSelected() 콜백 메서드를 구현합니다. 예를 들어, 다음은 Activity의 인터페이스 구현입니다.

public class SpinnerActivity extends Activity implements OnItemSelectedListener {
    ...

    public void onItemSelected(AdapterView<?> parent, View view,
            int pos, long id) {
        // An item was selected. You can retrieve the selected item using
        // parent.getItemAtPosition(pos)
    }

    public void onNothingSelected(AdapterView<?> parent) {
        // Another interface callback
    }
}

AdapterView.OnItemSelectedListener에는 onItemSelected() onNothingSelected() 콜백 메서드가 필요합니다.

그런 후 setOnItemSelectedListener()를 호출하여 인터페이스 구현을 지정해야 합니다.

 

Spinner spinner = (Spinner) findViewById(R.id.spinner);
spinner.setOnItemSelectedListener(this);

 

Activity 또는 Fragment를 사용하여 AdapterView.OnItemSelectedListener 인터페이스를 구현하는 경우(위의 예시 참조) this를 인터페이스 인스턴스로 전달하면 됩니다.

 

 

adapter나 리스너 구현이해가 어렵다면 다음 라이브러리와 같은 오픈소스를 사용하셔도 좋습니다.

github.com/arcadefire/nice-spinner

 

arcadefire/nice-spinner

A nice spinner for Android. Contribute to arcadefire/nice-spinner development by creating an account on GitHub.

github.com

 

참고: developer.android.com/guide/topics/ui/controls/spinner?hl=ko

 

반응형

+ Recent posts