2016-03-15 49 views
2

我新的EF和想從我的數據庫(SQLite的)以下列方式中的條目條款:實體框架6使用的parentid在與lambda表達式

類:

public class Customer 
{ 
    public Guid Id { get; set; } 
    public List<Month> Months { get; } = new List<Month>(); 
} 

public class Month 
{ 
    public int Id { get; set; } 
    public string CacheId { get; set; } 
    public string Data { get; set; } 
    [Required] 
    public Customer Customer { get; set; } 
} 

的DbContext:

public DbSet<Customer> Customers { get; set; } 
public DbSet<Month> Months { get; set; } 

用法:

using (var context = new CustomerContext()) 
{ 
    var customer = context.Customers.First(); 
    context.Database.Log = Console.WriteLine; 
    var shouldContainOneEntry = context.Months.Where(x => x.Customer.Id == customer.Id).ToList(); 
} 

shouldContainOneEntry不能爲空,但委託測試和靜態變量,而不是lambda表達式的工作:

private static Guid staticGuid; 
    public static bool DelegateTest(Month x) 
    { 
     return staticGuid == x.Customer.Id; 
    } 
    ... 
    staticGuid = customer.Id; 
    var workingVersion = context.Months.Where(DelegateTest).ToList(); 

生成的SQL看起來是正確的:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[CacheId] AS [CacheId], 
[Extent1].[Data] AS [Data], 
[Extent1].[Customer_Id] AS [Customer_Id] 
FROM [Months] AS [Extent1] 
WHERE [Extent1].[Customer_Id] = @p__linq__0 

-- p__linq__0: '5cfde6e0-5b3f-437b-84c8-2845b077462d' (Type = AnsiStringFixedLength, IsNullable = false) 

爲什麼與拉姆達版本表情不起作用?

+0

你是先使用代碼嗎? – Monah

+1

必須是與SQLLite查詢提供程序相關的內容。當你執行「委託版本」時,你調用了'Enumerable.Where',這意味着整個表在內存中被讀取,然後被過濾。 「lambda版本」應該生成你已經顯示的SQL。看起來SQLLite沒有原生的'Guid'支持,並且字符串轉換可能是錯誤的。如果您直接在數據庫中執行SELECT * FROM Months WHERE Customer_Id ='5cfde6e0-5b3f-437b-84c8-2845b077462d'',會發生什麼情況? –

+0

@Hadi Hassan:是的,我先使用代碼,生成的表看起來很好。 –

回答

1

該解決方案由以下IvanStoev的提示找到。

SQLite默認以二進制格式存儲Guid。爲此 像

SELECT * FROM Months WHERE CustomerId = '5cfde6e0-5b3f-437b-84c8-2845b077462d' 

的查詢提供了一個空的結果。 使用SQLite管理員,Guid以二進制格式顯示。 在VS中使用服務器資源管理器時,Guid以字符串格式顯示,這導致我得出錯誤結論,認爲這應該起作用。

將連接字符串的BinaryGUID選項設置爲false後,代碼正常工作。

+1

在更改實體之前,請檢查設置以下選項是否有助於[將GUID存儲爲文本](https://connectionstrings.com/sqlite-net-provider/store-guid-as-text/) –

+0

該選項有效,I更新了我的答案。再次感謝。 –

0

根據您的聲明

public class Customer 
{ 
    public Guid Id { get; set; } 
    public List<Month> Months { get; } = new List<Month>(); 
} 

public class Month 
{ 
    public int Id { get; set; } 
    public Guid CustomerId{get;set;} // you need to add the foreign Key of the customer (i will suppose that your foreign key in db called CustomerId 
    public string CacheId { get; set; } 
    public string Data { get; set; } 
    [Required] 
    [ForeignKey("CustomerId")] // and you need to tell EF which column is the foreign key 
    public Customer Customer { get; set; } 
} 

如何使用它現在

using (var context = new CustomerContext()) 
{ 
    var customer = context.Customers.First(); 
    context.Database.Log = Console.WriteLine; 
    var shouldContainOneEntry = context.Months.Where(x => x.CustomerId == customer.Id).ToList(); 
} 

希望它會幫助你

+0

ForeignKey應由EF確定。不需要使用ForeignKey屬性顯式設置它。 –