EF Code First의 계산된 열
데이터베이스에서 (행의 합계) - (행의 합계)로 계산되는 열이 데이터베이스에 하나 있어야 합니다.데이터베이스를 만들기 위해 코드 우선 모델을 사용하고 있습니다.
제 뜻은 다음과 같습니다.
public class Income {
[Key]
public int UserID { get; set; }
public double inSum { get; set; }
}
public class Outcome {
[Key]
public int UserID { get; set; }
public double outSum { get; set; }
}
public class FirstTable {
[Key]
public int UserID { get; set; }
public double Sum { get; set; }
// This needs to be calculated by DB as
// ( Select sum(inSum) FROM Income WHERE UserID = this.UserID)
// - (Select sum(outSum) FROM Outcome WHERE UserID = this.UserID)
}
EF CodeFirst에서 이를 실현하려면 어떻게 해야 합니까?
데이터베이스 테이블에 계산된 열을 생성할 수 있습니다.EF 모델에서는 해당 속성에 주석을 달기만 하면 됩니다.DatabaseGenerated★★★★
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public double Summ { get; private set; }
또는 유연한 매핑을 사용하는 경우:
modelBuilder.Entity<Income>().Property(t => t.Summ)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
Matija Grcic의 제안과 코멘트에서 보듯이, 이 자산을 만드는 것은 좋은 아이디어입니다.private set어플리케이션 코드로 설정하고 싶지 않을 수도 있기 때문입니다.엔티티 프레임워크는 개인 설정자에 문제가 없습니다.
주의: EF의 경우.HasDatabaseGeneratedOption이 존재하지 않기 때문에 다음과 같이 NET Core를 사용해야 합니다.
modelBuilder.Entity<Income>().Property(t => t.Summ)
.ValueGeneratedOnAddOrUpdate()
2019년 현재 EF core를 사용하면 다음과 같은 fluent API를 사용하여 열을 깔끔하게 계산할 수 있습니다.
「 」라고 합니다.DisplayName 속성을 할당하지.속성을 평소대로 정의해야 합니다.개인 속성 접근자를 사용하여 할당하지 않도록 할 수도 있습니다.
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// this will be computed
public string DisplayName { get; private set; }
}
그런 다음 모델 작성기에서 열 정의로 해당 주소를 지정합니다.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.Property(p => p.DisplayName)
// here is the computed query definition
.HasComputedColumnSql("[LastName] + ', ' + [FirstName]");
}
상세한 것에 대하여는, MSDN 를 참조해 주세요.
public string ChargePointText { get; set; }
public class FirstTable
{
[Key]
public int UserID { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string Summ
{
get { return /* do your sum here */ }
private set { /* needed for EF */ }
}
}
참고 자료:
EF6에서는 다음과 같이 계산된 속성을 무시하도록 매핑 설정을 구성할 수 있습니다.
모델의 get 속성에 대한 계산을 정의합니다.
public class Person
{
// ...
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName => $"{FirstName} {LastName}";
}
그런 다음 모델 구성에서 무시하도록 설정합니다.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//...
modelBuilder.Entity<Person>().Ignore(x => x.FullName)
}
한 가지 방법은 LINQ를 사용하는 것입니다.
var userID = 1; // your ID
var income = dataContext.Income.First(i => i.UserID == userID);
var outcome = dataContext.Outcome.First(o => o.UserID == userID);
var summ = income.inSumm - outcome.outSumm;
오브젝트 POCO 에서 실행할 수 .public class FirstTable좋은 디자인이 아니라고 생각하기 때문에 추천하고 싶지 않습니다.
다른 방법은 SQL 뷰를 사용하는 것입니다.Entity Framework를 사용하면 보기를 표처럼 읽을 수 있습니다.뷰 코드 내에서 계산이나 원하는 작업을 수행할 수 있습니다.다음과 같은 뷰를 생성하기만 하면 됩니다.
-- not tested
SELECT FirstTable.UserID, Income.inCome - Outcome.outCome
FROM FirstTable INNER JOIN Income
ON FirstTable.UserID = Income.UserID
INNER JOIN Outcome
ON FirstTable.UserID = Outcome.UserID
뷰 모델만 사용하면 됩니다.예를 들어 FirstTable 클래스를 DB 엔티티로 하는 것보다 FirstTable이라는 뷰 모델 클래스를 가지고 계산된 합계를 포함하는 이 클래스를 반환하는 데 사용되는 함수를 갖는 것이 더 낫지 않을까요?예를 들어 다음과 같은 클래스가 있습니다.
public class FirstTable {
public int UserID { get; set; }
public double Sum { get; set; }
}
그런 다음 계산된 합계를 반환하는 함수를 사용할 수 있습니다.
public FirsTable GetNetSumByUserID(int UserId)
{
double income = dbcontext.Income.Where(g => g.UserID == UserId).Select(f => f.inSum);
double expenses = dbcontext.Outcome.Where(g => g.UserID == UserId).Select(f => f.outSum);
double sum = (income - expense);
FirstTable _FirsTable = new FirstTable{ UserID = UserId, Sum = sum};
return _FirstTable;
}
기본적으로 SQL 뷰와 마찬가지로 @Linus가 언급했듯이 계산된 값을 데이터베이스에 유지하는 것은 좋지 않다고 생각합니다.그냥 몇 가지 생각일 뿐이야.
문자열 열 "Slug"을 가진 EF Code First 모델을 다른 문자열 열 "Name"에서 파생하려고 할 때 우연히 이 질문을 발견했습니다.제가 취한 접근법은 조금 달랐지만 잘 되었기 때문에 여기서 공유하겠습니다.
private string _name;
public string Name
{
get { return _name; }
set
{
_slug = value.ToUrlSlug(); // the magic happens here
_name = value; // but don't forget to set your name too!
}
}
public string Slug { get; private set; }
이 접근법의 좋은 점은 슬러그 세터를 노출시키지 않으면서 자동 슬러그 발생을 할 수 있다는 것입니다.ToUrlSlug() 메서드는 이 투고에서 중요한 부분이 아닙니다.필요한 작업을 하기 위해 그 대신 어떤 것도 사용할 수 있습니다.건배!
언급URL : https://stackoverflow.com/questions/15585330/calculated-column-in-ef-code-first
'programing' 카테고리의 다른 글
| 포스트그레스 자동 증가 카운터 재설정 (0) | 2023.04.12 |
|---|---|
| VBA: 조건부 - 아무것도 아니다 (0) | 2023.04.12 |
| UNION [ALL]에서 SELECT INTO 조항을 사용할 수 있습니까? (0) | 2023.04.07 |
| Dapper를 사용하여 삽입된 ID를 반환하려면 어떻게 해야 합니까? (0) | 2023.04.07 |
| 열 변경, 기본 제약 조건 추가 (0) | 2023.04.07 |