LINQ에서 SQL로:분리된 엔터티 개체 만들기
-
19-09-2019 - |
문제
LINQ to SQL을 사용하여 몇 가지 클래스를 생성했습니다.
그 중 하나가 "고객"입니다.
이제 연결이 끊어진 Customer 개체를 만들고 싶습니다.
즉.객체를 생성하여 세션에 유지한 다음 원하는 경우에만 다시 연결할 수 있습니다.자동으로 아닙니다.따라서 첨부하는 경우에만 내 컨텍스트의 SubmitChange()에 영향을 주어야 합니다. 그렇지 않으면 그렇지 않습니다.
이것이 가능한가?
또한 SubmitChanges()에 영향을 주지 않고 이 분리된 개체를 연결된 개체 컬렉션에 추가할 수 있습니까? 아니면 추가 시 분리된 개체가 다시 연결됩니까?
해결책
"Detach" 메서드는 없지만 직렬화를 사용하면 가능합니다.
Customer customerCopy;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, customer);
ms.Position = 0;
customerCopy = (Customer)bf.Deserialize(ms);
}
나중에 개체를 다시 부착하는 것은 번거롭다는 점에 유의하세요.그만큼 Attach
테이블 방법은 까다롭습니다. 일반적으로 Version
(타임스탬프 유형) 열이 작동하려면 엔터티에 대한 열이 있어야 합니다.
참고 - 방금 귀하의 질문을 다시 읽었는데 귀하가 단순히 원하는 것처럼 들립니다. 건설하다 그 물체.그렇다면 새로운 건물을 짓는 것은 Customer
~을 통해 new Customer()
~ 할 것이다 ~ 아니다 연결된 엔터티를 만듭니다.호출한 후에만 연결됩니다. InsertOnSubmit
또는 Attach
테이블 위의 방법.
또한 분리된 엔터티를 자유롭게 추가할 수 있습니다. List<Customer>
(또는 이와 유사한) 연결된 엔터티 포함 - Linq to SQL은 이에 대해 신경 쓰지 않으며 엔터티는 다음에 의해 분배되는 경우에만 연결됩니다. DataContext
위의 방법 중 하나를 사용하여 첨부하는 경우.
다른 팁
LINQ에서 SQL의 경우 DataContractSerializer 만 지원됩니다.
()를 분리하는 더 성능적인 방법이 있으며 다음과 같은 기본 방법을 사용하고 있습니다.
public void Detach()
{
GetType().GetMethod("Initialize", BindingFlags.Instance |
BindingFlags.NonPublic).Invoke(this, null);
}
이렇게하면 모든 FK 속성을 '재설정'할 초기화 () 메소드를 호출합니다. 속임수는이 방법이 직렬화가 켜져있을 때만 생성된다는 것입니다. 이 문제를 해결하는 방법이 있습니다. 여기 더 많은 정보를 위해서
Vitaliy, 그 블로그 포스트를 잃어 버려 죄송합니다. 그래도 여전히 코드가 있습니다.
public class EntityBase : IEntityBase
{
/// <summary>
/// Detaches the entity, so it can be added to another dataContext. It does this by setting
/// all the FK properties to null/default.
/// </summary>
public void Detach()
{
// I modified the .tt file to generate the Initialize method by default.
// The call to OnCreated() is moved to the constructor.
GetType().GetMethod("Initialize", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(this, null);
}
}
그리고 여기 내 어댑터에서 detach ()에 대한 호출이 있습니다.
public class OrderAdapter : IOrderAdapter
{
public void Add(IOrder order)
{
try
{
using (var db = new ATPDataContext())
{
Order newOrder = (Order)order;
newOrder.Detach(); // not required for insertion, but to keep references to Product
db.Orders.InsertOnSubmit(newOrder);
db.SubmitChanges();
}
}
catch (Exception ex)
{
}
}
}
그리고 내 .tt 파일에서
#region Construction
public <#=class1.Name#>()
{
Initialize();
<# if (class1.HasPrimaryKey) {#>
OnCreated();
<# } #>
}
private void Initialize()
{
<# foreach(Association association in class1.Associations) { #>
<#=association.Storage#> = <#
if (association.IsMany) {
#>new EntitySet<<#=association.Type.Name#>>(attach_<#=association.Member#>, detach_<#=association.Member#>);
<# } else {
#>default(EntityRef<<#=association.Type.Name#>>);
<# }
}
#>
}
#endregion
HTH!