F # Linq To SQL фиксация изменений ничего не делает - PullRequest
3 голосов
/ 26 января 2011

У меня есть следующий класс, определенный в F #, с атрибутами отображения для Linq на SQL:

[<Table(Name="Expense")>]
type public Expense(datetime : Nullable<DateTime>, value, category, comment) = 
    let mutable id = 0
    let mutable datetime = if datetime.HasValue then datetime.Value else DateTime.Now
    let mutable value = value
    let mutable category = category
    let mutable comment = comment
    [<Column(IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.OnInsert)>]
    member x.ExpenseID with get() = id and set v = id <- v
    [<Column>]
    member x.DateTime with get() = datetime and set v = datetime <- v
    [<Column>] 
    member x.Value with get() = value and set v = value <- v
    [<Column>] 
    member x.Category with get() = category and set v = category <- v    
    [<Column>] 
    member x.Comment with get() = comment and set v = comment <- v
    new() = Expense(nl, 0m, "", "")

Затем я хочу вставить новый объект этого типа, используя следующий код (фрагмент):

member private x.expenses = (new DataContext(connString)).GetTable<Expense>()
    member x.Add (expense : Expense) = 
        x.expenses.InsertOnSubmit(expense)
        x.expenses.Context.SubmitChanges()

Вызов SubmitChanges () ничего не делает, и никакое исключение не выдается.Поэтому я попытался проверить, есть ли что-то с этим объектом F #, и я объявил другой класс в C # с точно такими же отображениями.Тогда я смог вставить новую запись.Теперь мне интересно, в чем разница?

При некоторых исследованиях Reflector, единственное отличие - это атрибуты [CompilerGenerated] на автоматических средствах получения / установки C # и [Serializable] и CompilationMapping (SourceConstructFlags.ObjectType)] на F #класс ... это может быть один из них?

Разборка отражателя: http://pastebin.com/qTRfVcmm

// РЕДАКТИРОВАНИЕ

Выполнив некоторую отладку в коде .NET framework, я 'мы заметили, что внутренний список отслеживаемых объектов экземпляра DataContext не согласован между вызовами InsertOnSubmit и SubmitChanges.В начале вызова SubmitChanges этот список пуст.Это заставило меня задуматься, эти две ссылки не нацелены на один и тот же экземпляр DataContext, и отладчик VS подтвердил это.Тем не менее, понятия не имею, почему.

1 Ответ

6 голосов
/ 26 января 2011

Проблема при первом использовании member.Члены F # (без параметров) ведут себя как свойства, поэтому вы создаете новый контекст данных каждый раз, когда получаете доступ к x.expenses.Чтобы исправить это, вы можете сохранить объект таблицы в поле, используя let:

type SomeType() =
  let expenses = (new DataContext(connString)).GetTable<Expense>()     
  member x.Add (expense : Expense) =          
    expenses.InsertOnSubmit(expense)
    expenses.Context.SubmitChanges() 

Синтаксис member x.Foo = <expr> в F # соответствует свойству с getter, поэтому в синтаксисе C # ваш исходный кодбудет выглядеть так:

Table<Expenses> Expenses {
  get { return (new DataContext(connString)).GetTable<Expense>(); }
}

..., что объясняет, почему было создано несколько копий контекста данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...