using System;
using System.Linq.Expressions;
namespace Kyoo.Models
{
///
/// A class representing a link between two resources.
///
///
/// Links should only be used on the data layer and not on other application code.
///
public class Link
{
///
/// The ID of the first item of the link.
/// The first item of the link should be the one to own the link.
///
public int FirstID { get; set; }
///
/// The ID of the second item of this link
/// The second item of the link should be the owned resource.
///
public int SecondID { get; set; }
///
/// Create a new typeless .
///
public Link() {}
///
/// Create a new typeless with two IDs.
///
/// The ID of the first resource
/// The ID of the second resource
public Link(int firstID, int secondID)
{
FirstID = firstID;
SecondID = secondID;
}
///
/// Create a new typeless between two resources.
///
/// The first resource
/// The second resource
public Link(IResource first, IResource second)
{
FirstID = first.ID;
SecondID = second.ID;
}
///
/// Create a new typed link between two resources.
/// This method can be used instead of the constructor to make use of generic parameters deduction.
///
/// The first resource
/// The second resource
/// The type of the first resource
/// The type of the second resource
/// A newly created typed link with both resources
public static Link Create(T first, T2 second)
where T : class, IResource
where T2 : class, IResource
{
return new(first, second);
}
///
/// Create a new typed link between two resources without storing references to resources.
/// This is the same as but this method does not set
/// and fields. Only IDs are stored and not references.
///
/// The first resource
/// The second resource
/// The type of the first resource
/// The type of the second resource
/// A newly created typed link with both resources
public static Link UCreate(T first, T2 second)
where T : class, IResource
where T2 : class, IResource
{
return new(first, second, true);
}
///
/// The expression to retrieve the unique ID of a Link. This is an aggregate of the two resources IDs.
///
public static Expression> PrimaryKey
{
get
{
return x => new {First = x.FirstID, Second = x.SecondID};
}
}
}
///
/// A strongly typed link between two resources.
///
/// The type of the first resource
/// The type of the second resource
public class Link : Link
where T1 : class, IResource
where T2 : class, IResource
{
///
/// A reference of the first resource.
///
public T1 First { get; set; }
///
/// A reference to the second resource.
///
public T2 Second { get; set; }
///
/// Create a new, empty, typed .
///
public Link() {}
///
/// Create a new typed link with two resources.
///
/// The first resource
/// The second resource
///
/// True if no reference to resources should be kept, false otherwise.
/// The default is false (references are kept).
///
public Link(T1 first, T2 second, bool privateItems = false)
: base(first, second)
{
if (privateItems)
return;
First = first;
Second = second;
}
///
/// Create a new typed link with IDs only.
///
/// The ID of the first resource
/// The ID of the second resource
public Link(int firstID, int secondID)
: base(firstID, secondID)
{ }
///
/// The expression to retrieve the unique ID of a typed Link. This is an aggregate of the two resources IDs.
///
public new static Expression, object>> PrimaryKey
{
get
{
return x => new {First = x.FirstID, Second = x.SecondID};
}
}
}
}