문제

ASP.NET MVC 웹 사이트에서 MySQL (DBLINQ 사용)을 위해 LINQ에서 SQL을 사용하고 있습니다. 이상한 캐싱 문제가 있습니다. 내 저장소 클래스에서 다음 방법을 고려하십시오.

public IEnumerable<Message> GetInbox(int userId)
{
  using(MyDataContext repo = new MyDataContext(new MySqlConnection("[Connectionstring]")))
  {
    return repo.Messages.Where(m => m.MessageTo == userId);
  }
}

public IEnumerable<Message> GetOutbox(int userId)
{
  using (MyDataContext repo = new MyDataContext(new MySqlConnection("[Connectionstring]")))
  {
    return repo.Messages.Where(m => m.MessageFrom == userId);
  }
}

'MyDataconText'는 DATACONTEXT에서 상속되는 DBLINQ 생성 내 데이터베이스에 대한 매핑입니다. 나는 여기서 Datacontext를 재사용하지 않습니다 (위의 코드는 약간 어리석은 것처럼 보이지만 Datacontext / mysqlConnection 재사용 문제가 아닌지 확인하고 싶었습니다).

무슨 일이 일어나는지, 내가 부르는 두 가지 방법 중 어느 쪽이든, userID와 함께 결과는 동일하게 유지됩니다. 기간. 나는 그것을 볼 수 있지만 repo.Messages 다양한 결과가 있으며 다양한 결과가 있습니다 MessageFrom 그리고 MessageTo 값, 나는 첫 번째 결과 만 다시 얻습니다. 그래서 내가 전화하면 GetInbox(4374) 그것은 나에게 메시지 A와 메시지 B를 준다 GetInbox(526) 그 후에도 여전히 나에게 메시지 A와 B를 준다. ~이다 메시지 C와 D WHO 하다 526의 userId가 있습니다. 변경 사항을 확인하려면 응용 프로그램을 다시 시작해야합니다.

여기서 무슨 일이야? 나는 누군가가 나에게 그것을 가리킬 때 부끄러워 할 정도로 어리석은 일을하고 있다고 확신합니다. 내가 매우 어리석은 일을하지 않는다면이 문제가 매우 이상하다고 생각합니다. 나는 DataContext를 재사용하지 않는 것에 대해 읽었지만 그렇지 않습니다. 왜이 캐싱 문제가 있습니까? 아래는 내 컨트롤러 코드이지만 문제가 중요합니다.

[Authorize]
public ActionResult Inbox(int userId)
{
  Mailbox inbox = new Mailbox(userId, this.messageRepository.GetInbox(userId));
  return PartialView("Inbox", inbox);
}

SO에 비슷한 질문이 있지만이 정확한 질문에 대한 답을 찾지 못했습니다. 많은 감사합니다!

업데이트: 코드 변경 : return repo.Messages.ToList().Where(m => m.MessageFrom == userId); 그것을 고치고, 그것은 잘 작동합니다. 일부 캐시 문제처럼 보입니다. 그러나 물론 그런 식으로 고치고 싶지는 않습니다. 쿼리 후에 DataContext가 배치되지 않도록 코드 변경 ~ 아니다 문제를 해결.

도움이 되었습니까?

해결책 4

글쎄, 그것은 dblinq의 문제인 것 같았습니다. 3 주부터 소스 코드를 사용했는데 QueryCache에 뚜렷한 버그가있었습니다. 언제나 거기에 있었다). 이것을 다루는 완전한 스레드가 있습니다 여기.

DBLINQ 소스를 업데이트했습니다. QueryCache는 이제 비활성화되었습니다 (성능 히트를 의미합니다). 적어도 이제는 작동합니다. 성능이 허용되는지 확인해야합니다. 내가하려고하는 것은 일반적인 linq2sql 패턴이기 때문에 내가 약간 당황 스러웠다 고 고백해야합니다. 감사합니다.

다른 팁

나는 잘 작동하는 것처럼 보이는 꽤 비슷한 코드를 썼습니다. 유일한 차이점은 Marc가 제안한 것처럼 연결 문자열을 전달하고 Where Method에서 Tolist를 호출한다는 것입니다. 내 데이터베이스는 자동으로 생성되지 않지만 Datacontext에서 파생됩니다. 코드는 다음과 같습니다.

class Program
{
    static void Main(string[] args)
    {
        List<Item> first = GetItems("F891778E-9C87-4620-8AC6-737F6482CECB").ToList();
        List<Item> second = GetItems("7CA18DD1-E23B-41AA-871B-8DEF6228F96C").ToList();
        Console.WriteLine(first.Count);
        Console.WriteLine(second.Count);
        Console.Read();
    }

    static IEnumerable<Item> GetItems(string vendorId)
    {
        using (Database repo = new Database(@"connection_string_here"))
        {
            return repo.GetTable<Item>().Where(i => i.VendorId.ToString() == vendorId).ToList(); ;
        }
    }
}

테스트를 작성하여 시작합니다. LINQ2SQL이 올바르게 작동한다고 말할 것입니다. 같은 것 :

var inboxMessages = this.messageRepository.GetInbox(userId1);
Assert.That(inboxMessages.All(m => m.MessageTo == userId1);

inboxMessages = this.messageRepository.GetInbox(userid2);
Assert.That(inboxMessages.All(m => m.MessageTo = userid2);

그것이 성공한다면, 당신은 실제로 문제를 일으키는 지연된 실행인지 확인해야합니다. 받은 편지함을 즉시 열거해야합니다.

문제를 일으킬 수있는 또 다른 것은 DataContext가 이미 폐기 될 때 열거를 시작한다는 사실입니다. 이것을 해결하는 유일한 방법은 전혀 폐기하지 않는 것입니다 (GC가 범위를 벗어날 때 GC 청소에 의존하거나 사용자 정의 IDISPosable 객체를 생각해 내므로 주변에 사용을 넣을 수 있습니다. 같은 것 :

using(var inboxMessages = this.messageRepository.GetInbox(userId1))
{
    Assert.That(inboxMessages.All(m => m.MessageTo == userId1);
}

LINQ-to-SQL의 캐싱은 DataContext, 주로 신원 캐싱으로 제한됩니다. 대부분의 경우 쿼리를 이전에 해냈더라도 쿼리를 다시 실행합니다. 몇 가지 예가 있습니다 .Single(x=>x.Id == id) (특별한 취급이 있음).

당신은 매번 새로운 데이터 텍스트를 얻고 있기 때문에, 나는 그것이 범인이라고 생각하지 않습니다. 그러나 나는 또한 코드가 작동한다는 것에 약간 놀랐습니다 ... 그것이 대표적이라고 확신합니까?

LINQ Where 메소드는 지연됩니다 - 데이터를 반복 할 때까지 실행되지 않음을 의미합니다 (예 : foreach). 그러나 그때까지 당신은 이미 데이터 컨텍스트를 처분했습니다! 예에서 뭔가를 먹었습니까?

또한 - 그것을 제공함으로써 SqlConnection (그때는 그렇지 않습니다 Dispose()), 정리에 영향을 줄 수 있습니다. 연결 문자열을 (데이터 컨텍스트) 제공하는 것이 바람직 할 수 있습니다.

프로덕션 코드에는 DBLINQ를 사용하지 않습니다 ... 많은 LINQ-TO-SQL 기능이 구현되지 않았으며 소스 코드를 통과하는 수준의 성숙도가 낮습니다 ... 많은 방법이 구현되거나 표시되지 않습니다. "문명화되지 않은".

... 당신은 경고를 받았습니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top